Пример #1
0
 def render_property(self, name, mode, context, props):
     # No special treatment besides respecting newlines in values.
     value = props[name]
     if value and '\n' in value:
         value = Markup(''.join(['<br />%s' % escape(v)
                                 for v in value.split('\n')]))
     return value
Пример #2
0
    def _parse_heading(self, match, fullmatch, shorten):
        match = match.strip()

        depth = min(len(fullmatch.group('hdepth')), 5)
        anchor = fullmatch.group('hanchor') or ''
        heading_text = match[depth + 1:-depth - 1 - len(anchor)]
        out = StringIO()
        TiddlyWikiFormatter(self.env, self.req).format(heading_text, out)
        heading = Markup(out.getvalue().strip())
        if anchor:
            anchor = anchor[1:]
        else:
            sans_markup = heading.plaintext(keeplinebreaks=False)
            anchor = self._anchor_re.sub('', sans_markup)
            if not anchor or anchor[0].isdigit() or anchor[0] in '.-':
                # an ID must start with a Name-start character in XHTML
                anchor = 'a' + anchor  # keeping 'a' for backward compat
        i = 1
        anchor_base = anchor
        while anchor in self._anchors:
            anchor = anchor_base + str(i)
            i += 1
        self._anchors[anchor] = True
        if shorten:
            heading = wiki_to_oneliner(heading_text, self.env, self.db, True,
                                       self._absurls)
        return (depth, heading, anchor)
Пример #3
0
    def generate_help(self, target, inline=False, visibility=''):
        """Show documentation for named `target`.

        If `inline` is set, no header will be generated.
        For the `visibility` argument, see `PyDocMacro`.
        """
        try:
            if not target or target == 'index':
                if inline:
                    doc = ''
                else:
                    doc = html.h1('Python: Index of Modules')
                for dir in self.syspath:
                    if os.path.isdir(dir):
                        doc += Markup(
                            self.doc.index(dir,
                                           includes=self.includes,
                                           excludes=self.excludes))
                return doc
            else:
                if inline:
                    doc = ''
                else:
                    doc = html.h1('Python: Documentation for ',
                                  Markup(self.doc._dotted_path_links(target)))
                return doc + Markup(
                    to_unicode(self._makedoc(target, visibility)))
        except ImportError:
            return "No Python documentation found for '%s'" % target
Пример #4
0
 def trac_get_reference(env, context, rawtext, target, text):
     fulltext = target + ' ' + text if text else target
     link = extract_link(env, context, fulltext)
     uri = None
     missing = False
     if isinstance(link, (Element, Fragment)):
         linktext = Markup(link).striptags()
         # the following is a bit hackish, but it takes into account:
         #  - an eventual trailing '?' for missing wiki pages
         #  - space eventually introduced due to split_page_names option
         if linktext.rstrip('?').replace(' ', '') != target:
             text = linktext
         elt = find_element(link, 'href', 'missing')
         if elt is not None:
             uri = elt.attrib.get('href', '')
             missing = 'missing' in elt.attrib.get('class', '').split()
     else:
         uri = context.href.wiki(target)
         missing = not WikiSystem(env).has_page(target)
     if uri or missing:                    
         reference = nodes.reference(rawtext, text or target)
         reference['refuri'] = uri
         if missing:
             reference['classes'].append('missing')
         return reference
Пример #5
0
    def wiki_to_html(self, wikitext, req):
        self.env.log.debug('start function wiki_to_html') # pylint: disable-msg=E1101

        # Remove some macros (TOC is better handled in ODT itself)
        for macro in self.remove_macros:
            wikitext = re.sub('\[\[%s(\([^)]*\))?\]\]' % macro, "", wikitext)

        # Now convert wiki to HTML
        out = StringIO()
        context = Context.from_request(req, absurls=True)
        Formatter(self.env, # pylint: disable-msg=E1101
                  context('wiki', self.page_name)).format(wikitext, out)
        html = Markup(out.getvalue())
        html = html.encode("utf-8", 'replace')

        # Clean up the HTML
        html = re.sub('<span class="icon">.</span>', '', html) # Remove external link icon
        tidy_options = dict(output_xhtml=1, add_xml_decl=1, indent=1,
                            tidy_mark=0, input_encoding='utf8',
                            output_encoding='utf8', doctype='auto',
                            wrap=0, char_encoding='utf8')
        html = tidy.parseString(html, **tidy_options)
        # Replace nbsp with entity:
        # http://www.mail-archive.com/[email protected]/msg03670.html
        html = str(html).replace("&nbsp;", "&#160;")
        # Tidy creates newlines after <pre> (by indenting)
        html = re.sub('<pre([^>]*)>\n', '<pre\\1>', html)
        return html
Пример #6
0
    def _parse_heading(self, match, fullmatch, shorten):
        match = match.strip()

        depth = min(len(fullmatch.group('hdepth')), 5)
        anchor = fullmatch.group('hanchor') or ''
        heading_text = match[depth+1:-depth-1-len(anchor)]
        out = StringIO()
        TiddlyWikiFormatter(self.env, self.req).format(heading_text, out)
        heading = Markup(out.getvalue().strip())
        if anchor:
            anchor = anchor[1:]
        else:
            sans_markup = heading.plaintext(keeplinebreaks=False)
            anchor = self._anchor_re.sub('', sans_markup)
            if not anchor or anchor[0].isdigit() or anchor[0] in '.-':
                # an ID must start with a Name-start character in XHTML
                anchor = 'a' + anchor # keeping 'a' for backward compat
        i = 1
        anchor_base = anchor
        while anchor in self._anchors:
            anchor = anchor_base + str(i)
            i += 1
        self._anchors[anchor] = True
        if shorten:
            heading = wiki_to_oneliner(heading_text, self.env, self.db, True,
                                       self._absurls)
        return (depth, heading, anchor)
Пример #7
0
 def test_check(self):
     check = BasicCheck(self.env)
     req = self.req
     # Inspector doesn't provide additional fields.
     field_res = check.render_registration_fields(req, {})
     self.assertEqual(len(field_res), 2)
     self.assertEqual((Markup(field_res[0]), field_res[1]),
                      (Markup(''), {}))
     # 1st attempt: No input.
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 2nd attempt: Illegal character.
     req.args['username'] = '******'
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 3rd attempt: All upper-case word.
     req.args['username'] = '******'
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 4th attempt: Reserved word.
     req.args['username'] = '******'
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 5th attempt: Existing user.
     req.args['username'] = '******'
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 6th attempt: Valid username, but no password.
     req.args['username'] = '******'
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 7th attempt: Valid username, no matching passwords.
     req.args['password'] = '******'
     self.assertRaises(RegistrationError, check.validate_registration, req)
     # 8th attempt: Finally some valid input.
     req.args['password_confirm'] = 'password'
     self.assertEqual(check.validate_registration(req), None)
Пример #8
0
 def test_tag(self):
     self.assertEqual(Markup('0<a>0</a> and <b>0</b> and <c></c>'
                             ' and <d class="a b" more_="[\'a\']"></d>'),
                      Markup(tag(0, tag.a(0, href=''), b' and ', tag.b(0.0),
                                 ' and ', tag.c(None), ' and ',
                                 tag.d('', class_=['a', '', 'b'],
                                       more__=[b'a']))))
Пример #9
0
 def trac_get_reference(env, context, rawtext, target, text):
     fulltext = target + ' ' + text if text else target
     link = extract_link(env, context, fulltext)
     uri = None
     missing = False
     if isinstance(link, (Element, Fragment)):
         linktext = Markup(link).striptags()
         # the following is a bit hackish, but it takes into account:
         #  - an eventual trailing '?' for missing wiki pages
         #  - space eventually introduced due to split_page_names option
         if linktext.rstrip('?').replace(' ', '') != target:
             text = linktext
         elt = find_element(link, 'href', 'missing')
         if elt is not None:
             uri = elt.attrib.get('href', '')
             missing = 'missing' in elt.attrib.get('class', '').split()
     else:
         uri = context.href.wiki(target)
         missing = not WikiSystem(env).has_page(target)
     if uri or missing:
         reference = nodes.reference(rawtext, text or target)
         reference['refuri'] = uri
         if missing:
             reference['classes'].append('missing')
         return reference
Пример #10
0
    def test_check(self):
        check = BotTrapCheck(self.env)
        req = self.req

        # Inspector provides the email text input field.
        wrong_input = "Hey, I'm a bot."
        data = dict(basic_token=wrong_input)
        req.args.update(data)
        field_res = check.render_registration_fields(req, data)
        self.assertEqual(len(field_res), 2)
        self.assertTrue(Markup(field_res[0]).startswith('<label>Parole:'))

        # 1st attempt: Wrong input.
        self.assertRaises(RegistrationError, check.validate_registration, req)
        # Ensure, that old input is restored on failure.
        self.assertTrue(wrong_input in Markup(field_res[0]))
        # Ensure, that template data dict is passed unchanged.
        self.assertEqual(field_res[1], data)

        # 2nd attempt: No input.
        req.args['basic_token'] = ''
        self.assertRaises(RegistrationError, check.validate_registration, req)
        # 3rd attempt: As before, but request done by authenticated user.
        req = Mock(authname='admin', args=self.req.args)
        self.assertEqual(check.validate_registration(req), None)
        # 4th attempt: Finally valid input.
        req = self.req
        req.args['basic_token'] = self.basic_token
        self.assertEqual(check.validate_registration(req), None)
        # 5th attempt: Fill the hidden field too.
        req.args['sentinel'] = "Humans can't see this? Crap - I'm superior!"
        self.assertRaises(RegistrationError, check.validate_registration, req)
Пример #11
0
    def get_timeline_events(self, req, start, stop, filters):
        format = req.args.get('format')

        status_map = {
            'new': ('newticket', u'créé'),
            'reopened': ('newticket', u'réouvert'),
            'closed': ('closedticket', u'fermé'),
            'edit': ('editedticket', u'mis à jour')
        }

        href = format == 'rss' and req.abs_href or req.href

        def produce(
            (id, t, author, type, summary), status, fields, comment, cid):
            if status == 'edit':
                if 'ticket_details' in filters:
                    info = u''
                    if len(fields) > 0:
                        info = u', '.join([u'<i>%s</i>' % f for f in \
                                          fields.keys()]) + u' modifié<br />'
                else:
                    return None
            elif 'ticket' in filters:
                if status == 'closed' and fields.has_key('resolution'):
                    info = fields['resolution']
                    if info and comment:
                        info = '%s: ' % info
                else:
                    info = ''
            else:
                return None
            kind, verb = status_map[status]
            if format == 'rss':
                title = u'Ticket #%s (%s %s): %s' % \
                        (id, translate(self.env, type).lower(), verb, summary)
            else:
                title = Markup(
                    u'Ticket <em title="%s">#%s</em> (%s) %s par %s', summary,
                    id, translate(self.env, type), verb, author)
            ticket_href = href.ticket(id)
            if cid:
                ticket_href += '#comment:' + cid
            if status == 'new':
                message = unicode(summary)
            else:
                message = Markup(info)
                if comment:
                    if format == 'rss':
                        message += wiki_to_html(comment,
                                                self.env,
                                                req,
                                                db,
                                                absurls=True)
                    else:
                        message += wiki_to_oneliner(comment,
                                                    self.env,
                                                    db,
                                                    shorten=True)
            return kind, ticket_href, title, t, author, message
Пример #12
0
    def post_process_request(self, req, template, data, content_type):
        if data and req.path_info == '/timeline' and \
                'TAGS_VIEW' in req.perm(Resource('tags')):

            def realm_handler(_, node, context):
                return query.match(node, [context.realm])

            query_str = req.args.getfirst(self.key)
            if query_str is None and req.args.get('format') != 'rss':
                query_str = req.session.get('timeline.%s' % self.key)
            else:
                query_str = (query_str or '').strip()
                # Record tag query expression between visits.
                req.session['timeline.%s' % self.key] = query_str

            if data.get('events') and query_str:
                tag_system = TagSystem(self.env)
                try:
                    query = Query(query_str,
                                  attribute_handlers={'realm': realm_handler})
                except InvalidQuery as e:
                    add_warning(req, _("Tag query syntax error: %s" % e))
                else:
                    all_realms = tag_system.get_taggable_realms(req.perm)
                    query_realms = set()
                    for m in REALM_RE.finditer(query.as_string()):
                        query_realms.add(m.group(1))
                    # Don't care about resources from non-taggable realms.
                    realms = not query_realms and all_realms or \
                             query_realms.intersection(all_realms)
                    events = []
                    self.log.info("Filtering timeline events by tags '%s'",
                                   query_str)
                    for event in data['events']:
                        resource = resource_from_event(event)
                        if resource and resource.realm in realms:
                            # Shortcut view permission checks here.
                            tags = tag_system.get_tags(None, resource)
                            if query(tags, context=resource):
                                events.append(event)
                    # Overwrite with filtered list.
                    data['events'] = events
            if query_str:
                # Add current value for next form rendering.
                data[self.key] = query_str
            elif self.key in req.session:
                del req.session[self.key]

            filter_lst = []
            # xpath = '//form[@id="prefs"]/div[1]'
            xform = JTransformer('form#prefs > div:nth-of-type(1)')
            insert = builder(Markup('<br />'), tag_("matching tags "),
                             builder.input(type='text', name=self.key,
                                           value=data.get(self.key)))
            filter_lst.append(xform.append(Markup(insert)))
            add_script_data(req, {'tags_filter': filter_lst})
            add_script(req, 'tags/js/tags_jtransform.js')

        return template, data, content_type
Пример #13
0
    def post_process_request(self, req, template, content_type):
        if req.path_info.startswith('/ticket'):
            tkt_id = req.path_info[8:]

            # jQuery!
            add_script(req, 'mastertickets/jquery.js')

            # Add in the 'Blocked by' field
            blocking_ids = blocked_by(self.env, tkt_id)
            if blocking_ids:
                req.hdf['ticket.blockedby'] = ', '.join(
                    [str(x) for x in blocking_ids])
                req.hdf['ticket.fields.blockedby'] = {
                    'value': '',
                    'custom': 1,
                    'type': 'text',
                    'label': 'Blocked By',
                    'order':
                    10,  # Force this to be at the end, since I am going to disappear it.
                }
                add_stylesheet(req, 'mastertickets/ticket.css')
                add_script(req, 'mastertickets/linkify_blockedby.js')

                # If any blockers are not closed, disable the resovle option
                img_src, img_alt = 'checkmark.gif', 'Blockers closed'
                for i in blocking_ids:
                    if Ticket(self.env, i)['status'] != 'closed':
                        if Ticket(self.env, tkt_id)['status'] != 'closed':
                            add_script(req, 'mastertickets/disable_resolve.js')
                            img_src, img_alt = 'x.png', 'Blockers open'
                        else:
                            img_src, img_alt = 'caution.png', 'Blockers open, but current ticket closed'

                # Magic stuff in the footer
                req.hdf['project.footer'] = Markup(
                    req.hdf['project.footer'] + Markup(
                        html.DIV(html.IMG(class_='blockedby_icon',
                                          src=req.href.chrome(
                                              'mastertickets', img_src),
                                          alt=img_alt,
                                          title=img_alt),
                                 ' ',
                                 linkify_ids(self.env, req, blocking_ids),
                                 id='linkified_blockedby',
                                 style='display:none')))

            # Linkify the 'Blocks' field
            blocks_ids = req.hdf.get('ticket.blocking') or ''
            blocks_ids = blocks_ids.replace('#', '')
            if blocks_ids:
                blocks_ids = [x.strip() for x in blocks_ids.split(',')]
                req.hdf['project.footer'] = Markup(
                    req.hdf['project.footer'] + Markup(
                        html.DIV(linkify_ids(self.env, req, blocks_ids),
                                 id='linkified_blocking',
                                 style='display:none')))
                add_script(req, 'mastertickets/linkify_blocking.js')

        return template, content_type
Пример #14
0
 def test_xml(self):
     self.assertEqual(Markup('0<a>0</a> and <b>0</b> and <c/> and'
                             ' <d class="[\'a\', \'\', \'b\']"'
                             ' more_="[\'a\']"/>'),
                      Markup(xml(0, xml.a(0), ' and ', xml.b(0.0),
                                 ' and ', xml.c(None), ' and ',
                                 xml.d('', class_=[b'a', b'', b'b'],
                                       more__=[b'a']))))
Пример #15
0
 def render_def(s):
     rendered = s and render_item(s) or None
     if isinstance(s, str):
         s = Markup(s.replace('&', '&amp;'))
     return [
         tag.td(rendered, nbsp, style='border:none'),
         tag.td(tag.kbd(s), style=value_style)
     ]
Пример #16
0
def render_node_property(env, name, value):
    """Renders a node property value to HTML.

    Currently only handle multi-line properties. See also #1601.
    """
    if value and '\n' in value:
        value = Markup(''.join(['<br />%s' % escape(v)
                                for v in value.split('\n')]))
    return value
Пример #17
0
def render_node_property(env, name, value):
    """Renders a node property value to HTML.

    Currently only handle multi-line properties. See also #1601.
    """
    if value and '\n' in value:
        value = Markup(''.join(
            ['<br />%s' % escape(v) for v in value.split('\n')]))
    return value
Пример #18
0
    def expand_macro(self, formatter, name, args):
        if not args:
            return Markup()

        config = None
        if name == self.CONFIG_KEY:
            lines = args.splitlines()
            if not lines or not lines[0].startswith('#!'):
                return Markup()
            config = self._parse_config([i.strip() for i in lines[0][2:].split(',')])
        else:
            config = self.CONFIG[name]

        if not config:
            return Markup()

        def to_html(text):
            if not text:
                return ''
            return Markup('<br>'.join([format_to_oneliner(self.env, formatter.context, line) \
                                for line in text.splitlines()]))

        def has_keys(dict, keys):
            for key in keys:
                if dict.has_key(key):
                    return True
            return False

        rows = self.parse_doc(args)
        if not rows:
            return Markup()

        seen = []
        for desc, keys in config:
            if [row for row in rows if has_keys(row, keys)]:
                seen.append(desc)

        thead = tag.thead()
        for desc, keys in config:
            if not desc in seen:
                continue
            thead(tag.td(tag.b(desc)))

        tbody = tag.tbody()
        for row in rows:
            trow = tag.tr()
            for desc, keys in config:
                if not desc in seen:
                    continue
                tcol = tag.td()
                for key in keys:
                    if row.has_key(key):
                        tcol(to_html(row[key]))
                trow(tcol)
            tbody(trow)

        return tag.table([thead, tbody], class_='wiki')
Пример #19
0
 def test_sanitize_remove_script_elem(self):
     markup = Markup('<script>alert("Foo")</script>')
     self.assertEquals('', markup.sanitize())
     markup = Markup('<SCRIPT SRC="http://example.com/"></SCRIPT>')
     self.assertEquals('', markup.sanitize())
     markup = Markup('<SCR\0IPT>alert("foo")</SCR\0IPT>')
     self.assertRaises(HTMLParseError, markup.sanitize)
     markup = Markup('<SCRIPT&XYZ SRC="http://example.com/"></SCRIPT>')
     self.assertRaises(HTMLParseError, markup.sanitize)
Пример #20
0
    def end_process(self, numrows):
        notmodifiedcount = numrows - len(self.added) - len(self.modified)
        self.message = 'Scroll to see a preview of the tickets as they will be imported. If the data is correct, select the \'\'\'Execute Import\'\'\' button.\n' + ' * ' + str(
            numrows) + ' tickets will be imported (' + str(len(
                self.added)) + ' added, ' + str(len(
                    self.modified)) + ' modified, ' + str(
                        notmodifiedcount) + ' unchanged).\n' + self.message
        self.data['message'] = Markup(self.styles) + wiki_to_html(
            self.message, self.env, self.req) + Markup('<br/>')

        return 'import_preview.html', self.data, None
Пример #21
0
 def _render_macro_FaceImg(self, req, content):
     uid = content
     rn = self.get_realname(uid)
     if not rn:
         raise Exception("unknown user")
     if self._jpegPhoto_width:
         return Markup(
             html.IMG(src=req.href.user("%s/jpegPhoto" % uid),
                      alt=rn,
                      width=self._jpegPhoto_width))
     return Markup(html.IMG(src=req.href.user("%s/jpegPhoto" % uid),
                            alt=rn))
Пример #22
0
    def process_request(self, req):
        from tractags.macros import TagMacros
        from tractags.parseargs import parseargs
        from trac.web.chrome import add_stylesheet

        req.perm.require('TAGS_VIEW')

        add_stylesheet(req, 'tags/css/tractags.css')
        data = {}

        def update_from_req(args):
            for k in req.args.keys():
                args[k] = unicode(req.args.get(k))

        if not req.args.has_key('e') and re.match('^/tags/?$', req.path_info):
            index = self.env.config.get('tags', 'index', 'cloud')
            index_kwargs = {'smallest': 10, 'biggest': 30}
            _, config_kwargs = parseargs(
                self.env.config.get('tags', 'index.args', ''))
            index_kwargs.update(config_kwargs)
            update_from_req(index_kwargs)

            if index == 'cloud':
                data['tag_body'] = Markup(
                    TagMacros(self.env).render_tagcloud(req, **index_kwargs))
            elif index == 'list':
                data['tag_body'] = Markup(
                    TagMacros(self.env).render_listtagged(req, **index_kwargs))
            else:
                raise TracError("Invalid index style '%s'" % index)
        else:
            _, args = parseargs(self.env.config.get('tags', 'listing.args',
                                                    ''))
            if req.args.has_key('e'):
                expr = req.args.get('e')
            else:
                expr = req.path_info[6:]
            data['tag_title'] = Markup(
                'Objects matching the expression <i>%s</i>' % escape(expr))
            data['tag_expression'] = expr
            try:
                Expression(expr)
            except Exception, e:
                data['tag_expression_error'] = unicode(e).replace(
                    ' (line 1)', '')
            args['expression'] = expr
            tags = []
            update_from_req(args)
            data['tag_body'] = Markup(
                TagMacros(self.env).render_listtagged(req, *tags, **args))
Пример #23
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'changeset' in filters:
            format = req.args.get('format')
            wiki_format = self.wiki_format_messages
            show_files = self.timeline_show_files
            db = self.env.get_db_cnx()
            repos = self.env.get_repository(req.authname)
            for chgset in repos.get_changesets(start, stop):
                message = chgset.message or '--'
                if wiki_format:
                    shortlog = wiki_to_oneliner(message, self.env, db,
                                                shorten=True)
                else:
                    shortlog = shorten_line(message)

                if format == 'rss':
                    title = Markup('Changeset [%s]: %s', chgset.rev, shortlog)
                    href = req.abs_href.changeset(chgset.rev)
                    if wiki_format:
                        message = wiki_to_html(message, self.env, req, db,
                                               absurls=True)
                    else:
                        message = html.PRE(message)
                else:
                    title = Markup('Changeset <em>[%s]</em> by %s', chgset.rev,
                                   chgset.author)
                    href = req.href.changeset(chgset.rev)

                    if wiki_format:
                        if self.timeline_long_messages:
                            message = wiki_to_html(message, self.env, req, db,
                                                   absurls=True)
                        else:
                            message = wiki_to_oneliner(message, self.env, db,
                                                       shorten=True)
                    else:
                        message = shortlog

                if show_files and req.perm.has_permission('BROWSER_VIEW'):
                    files = []
                    for chg in chgset.get_changes():
                        if show_files > 0 and len(files) >= show_files:
                            files.append(html.LI(Markup('&hellip;')))
                            break
                        files.append(html.LI(html.DIV(class_=chg[2]),
                                             chg[0] or '/'))
                    message = html.UL(files, class_="changes") + message

                yield 'changeset', href, title, chgset.date, chgset.author,\
                      message
Пример #24
0
    def end_process(self, numrows):
        self.message = 'Scroll to see a preview of the tickets as they will be imported. If the data is correct, select the \'\'\'Execute Import\'\'\' button.\n' + ' * ' + str(
            numrows
        ) + ' tickets will be imported (' + str(self.added) + ' added, ' + str(
            self.modifiedcount) + ' modified, ' + str(
                self.notmodifiedcount) + ' unchanged).\n' + self.message
        self.req.hdf['report.description'] = Markup(
            self.styles
        ) + wiki_to_html(self.message, self.env, self.req) + Markup(
            '<br/><form action="importer" method="post"><input type="hidden" name="action" value="import" /><div class="buttons"><input type="submit" name="cancel" value="Cancel" /><input type="submit" value="Execute import" /></div></form>'
        )

        self.req.hdf['report.numrows'] = numrows
        self.req.hdf['report.mode'] = 'list'
        return 'report.cs', None
Пример #25
0
def wiki_to_oneliner(env,
                     wikitext,
                     path,
                     basepath,
                     db=None,
                     shorten=False,
                     absurls=False,
                     req=None):
    if not wikitext:
        return Markup()
    out = StringIO()
    context = Context.from_request(req, absurls=False)
    OneLinerTexFormatter(env, context, path,
                         basepath).format(wikitext, out, shorten)
    return Markup(out.getvalue())
Пример #26
0
    def expand_macro(self, formatter, name, content):

        arg, kwarg = parse_args(content)

        includepattern = kwarg.get('include', '')
        #excludepattern = kwarg.get('exclude', '')
        length = int(kwarg.get('max', -1))
        ignorenoduedate = kwarg.get('ignore') == 'noduedate' or None

        if length == -1:
            length = None

        out = StringIO()

        include = re.compile(includepattern)
        #exclude = re.compile(excludepattern)

        milestones = []

        for milestone in Milestone.select(self.env, include_completed=False):
            if include.match(
                    milestone.name):  # and not exclude.match(milestone.name):
                milestones.append(milestone)

        out.write('<ul>\n')
        for milestone in milestones[0:length]:

            if milestone.due:
                #TODO: add one day to tdelta
                tdelta = (to_timestamp(milestone.due) -
                          to_timestamp(datetime.now(formatter.req.tz)))
                if tdelta > 0:
                    date = format_date(milestone.due, '%Y-%m-%d',
                                       formatter.req.tz)
                else:
                    date = None
            elif not ignorenoduedate:
                date = Markup('<i>(Unspecified)</i>')
            else:
                date = None

            if date:
                out.write('<li>%s - <a href="%s">%s</a></li>\n' %
                          (date, self.env.href.milestone(
                              milestone.name), milestone.name))

        out.write('</ul>\n')
        return Markup(out.getvalue())
Пример #27
0
 def _check_quickjump(self, req, noquickjump, kwd):
     """Look for search shortcuts"""
     # Source quickjump  FIXME: delegate to ISearchSource.search_quickjump
     quickjump_href = None
     if kwd[0] == '/':
         quickjump_href = req.href.browser(kwd)
         name = kwd
         description = _('Browse repository path %(path)s', path=kwd)
     else:
         context = web_context(req, 'search')
         link = find_element(extract_link(self.env, context, kwd), 'href')
         if link is not None:
             quickjump_href = link.attrib.get('href')
             name = link.children
             description = link.attrib.get('title', '')
     if quickjump_href:
         # Only automatically redirect to local quickjump links
         if not quickjump_href.startswith(req.base_path or '/'):
             noquickjump = True
         if noquickjump:
             return {'href': quickjump_href, 'name': tag.em(name),
                     'description': description}
         else:
             help_url = req.href.wiki('TracSearch') + '#Quicksearches'
             search_url = req.href.search(q=kwd, noquickjump=1)
             # FIXME: use tag_
             add_notice(req, Markup(_(
                 'You arrived here through the <a href="%(help_url)s">'
                 'quick-jump</a> search feature. To instead search for the '
                 'term <strong>%(term)s</strong>, click <a '
                 'href="%(search_url)s">here</a>.',
                 help_url=escape(help_url), term=escape(kwd),
                 search_url=escape(search_url))))
             req.redirect(quickjump_href)
Пример #28
0
 def test_sanitize_remove_style_scripts(self):
     # Inline style with url() using javascript: scheme
     markup = Markup('<DIV STYLE=\'background: url(javascript:alert("foo"))\'>')
     self.assertEquals('<div>', markup.sanitize())
     # Inline style with url() using javascript: scheme, using control char
     markup = Markup('<DIV STYLE=\'background: url(&#1;javascript:alert("foo"))\'>')
     self.assertEquals('<div>', markup.sanitize())
     # Inline style with url() using javascript: scheme, in quotes
     markup = Markup('<DIV STYLE=\'background: url("javascript:alert(foo)")\'>')
     self.assertEquals('<div>', markup.sanitize())
     # IE expressions in CSS not allowed
     markup = Markup('<DIV STYLE=\'width: expression(alert("foo"));\'>')
     self.assertEquals('<div>', markup.sanitize())
     markup = Markup('<DIV STYLE=\'background: url(javascript:alert("foo"));'
                                  'color: #fff\'>')
     self.assertEquals('<div style="color: #fff">', markup.sanitize())
Пример #29
0
    def test_bad_check(self):
        class BadRegistrationInspector(GenericRegistrationInspector):
            """Child class, that is left as a pure copy of its base.

            Bad check class example, because check method is not implemented.
            """

        check = BadRegistrationInspector(self.env)
        # Default (empty) response for providing additional fields is safe.
        field_res = check.render_registration_fields(self.req, {})
        self.assertEqual(len(field_res), 2)
        self.assertEqual((Markup(field_res[0]), field_res[1]),
                         (Markup(''), {}))
        # Check class without 'validate_registration' implementation fails.
        self.assertRaises(NotImplementedError, check.validate_registration,
                          self.req)
Пример #30
0
    def _render_full_format(self, formatter, post_list, post_instances,
                            heading, max_size, show_meta):
        """ Renters full blog posts. """
        out = ''
        if 'BLOG_VIEW' in formatter.req.perm('blog'):
            out = tag.div(class_="blog")
            out.append(
                tag.div(tag.a(heading, href=formatter.req.href.blog()),
                        class_="blog-list-title"))
            for post in post_instances:
                data = {
                    'post':
                    post,
                    'blog_personal_blog':
                    self.config.getbool('fullblog', 'personal_blog'),
                    'list_mode':
                    True,
                    'show_meta':
                    show_meta,
                    'execute_blog_macro':
                    True
                }
                if max_size:
                    data['blog_max_size'] = max_size

                txt = Chrome(self.env).render_template(
                    formatter.req, 'fullblog_macro_post.html', data,
                    {'fragment': True})
                out.append(Markup(to_unicode(txt)))
        return out
Пример #31
0
class SQLScalar(WikiMacroBase):
    """Output a number from a scalar (1x1) SQL query.
     
    Examples:
    {{{
        {{{
        #!SQLScalar
            SELECT count(id) as 'Number of Tickets'
            FROM ticket
        }}}
    }}}
    """

    # IWikiMacroBase methods
    def expand_macro(self, formatter, name, content):
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        try:
            cursor.execute(content)
        except Exception, e:
            return system_message(_("Invalid SQL"), exception_to_unicode(e))

        value = "Unknown"
        for row in cursor:
            value = unicode(row[0])
            break

        out = StringIO()
        print >> out, u"<span class='wikiscalar'>%s</span>" % value

        add_stylesheet(formatter.req, 'wikitable/css/wikitable.css')
        return Markup(out.getvalue())
Пример #32
0
 def change_sid(self, new_sid):
     assert self.req.authname == 'anonymous', \
            'Cannot change ID of authenticated session'
     assert new_sid, 'Session ID cannot be empty'
     if new_sid == self.sid:
         return
     db = self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute("SELECT sid FROM session WHERE sid=%s", (new_sid, ))
     if cursor.fetchone():
         raise TracError(
             Markup(
                 'Session "%s" already exists.<br />'
                 'Please choose a different session ID.', new_sid),
             'Error renaming session')
     self.env.log.debug('Changing session ID %s to %s' %
                        (self.sid, new_sid))
     cursor.execute(
         "UPDATE session SET sid=%s WHERE sid=%s "
         "AND authenticated=0", (new_sid, self.sid))
     cursor.execute(
         "UPDATE session_attribute SET sid=%s "
         "WHERE sid=%s and authenticated=0", (new_sid, self.sid))
     db.commit()
     self.sid = new_sid
     self.bake_cookie()
Пример #33
0
    def render_macro(self, req, name, content):

        self.view = ""

        self.render(req)

        return Markup(self.view)
Пример #34
0
    def render_macro(self, req, name, content):
        if not (req.perm.has_permission('TICKET_VIEW') or 
                req.perm.has_permission('TICKET_VIEW_CC')):
            raise TracError('TICKET_VIEW or TICKET_VIEW_CC permission required')
        options = copy.copy(DEFAULT_OPTIONS)
        if content:
            for arg in content.split(','):
                i = arg.index('=')
                options[arg[:i].strip()] = arg[i+1:].strip()
        db = self.env.get_db_cnx()
        options = parse_options(db, options)
        milestone = options['milestone']
        cursor = db.cursor()
        cursor.execute("SELECT owner, p.value "
                       "  FROM ticket t, ticket_custom p"
                       "  WHERE p.ticket = t.id and p.name = %s"
                       "  AND t.milestone = %s", [self.estimation_field, milestone])
        sum = 0.0
        estimations = {}
        for owner, estimation in cursor:
            try:
                sum += float(estimation)
                if estimations.has_key(owner):
                    estimations[owner] += float(estimation)
                else:
                    estimations[owner] = float(estimation)
            except:
                pass

        estimations_string = []
        labels = []
        for owner, estimation in estimations.iteritems():
            labels.append("%s %sh" % (owner, str(int(estimation))))
            estimations_string.append(str(int(estimation)))
            
        # Title
        title = 'Workload'

        # calculate remaining work time
        if options.get('today') and options.get('enddate'):
            currentdate = options['today']
            day = timedelta(days=1)
            days_remaining = 0
            while currentdate <= options['enddate']:
                if currentdate.weekday() < 5:
                    days_remaining += 1
                currentdate += day
            title += ' %sh (%s workdays left)' % (int(sum), days_remaining)
                
                
        return Markup("<img src=\"http://chart.apis.google.com/chart?"
               "chs=%sx%s" 
               "&amp;chd=t:%s"
               "&amp;cht=p3"
               "&amp;chtt=%s"
               "&amp;chl=%s"
               "&amp;chco=%s\" "
               "alt=\'Workload Chart\' />" 
               % (options['width'], options['height'], ",".join(estimations_string), 
                  title, "|".join(labels), options['color']))
Пример #35
0
 def get_timeline_events(self, req, start, stop, filters):
     if 'milestone' in filters:
         format = req.args.get('format')
         db = self.env.get_db_cnx()
         cursor = db.cursor()
         cursor.execute(
             "SELECT completed,name,description FROM milestone "
             "WHERE completed>=%s AND completed<=%s", (
                 start,
                 stop,
             ))
         for completed, name, description in cursor:
             title = Markup('Milestone <em>%s</em> completed', name)
             if format == 'rss':
                 href = req.abs_href.milestone(name)
                 message = wiki_to_html(description,
                                        self.env,
                                        req,
                                        db,
                                        absurls=True)
             else:
                 href = req.href.milestone(name)
                 message = wiki_to_oneliner(description,
                                            self.env,
                                            db,
                                            shorten=True)
             yield 'milestone', href, title, completed, None, message or '--'
Пример #36
0
    def get_info(self, event_providers):
        # TODO: There are supposed benefits to switching from a XML to JSON event source
        # http://simile.mit.edu/wiki/JSON_event_source:_use_js_Date%28%29_objects
    
        self.req.hdf['event_url'] = self.req.href.requirement() # TODO: This needs to be changed to a local source
        self.req.hdf['event_section'] = 'timeline' # TODO: This needs to be changed to a local source
        events = []
        
        start = 0
        stop = time.time()
        filters = ['milestone', 'ticket', 'changeset', 'wiki', 'requirement']
        for event_provider in event_providers:
            #try:
                for kind, href, title, date, author, message in event_provider.get_timeline_events(self.req, start, stop, filters):
                    # TODO: revisit this code... string escaping is still an issue
                    # Strip/escape HTML markup
                    #if isinstance(title, Markup):
                    #    title = title.plaintext(keeplinebreaks=False)
                    if not isinstance(title, Markup):
                        title = Markup(title)
                    title = title.plaintext(keeplinebreaks=False)
                    #title = title.stripentities()
                    message = to_unicode(message)
                    
                    events.append({
                      # Everything but data will be inserted as attributes into an event tag
                      # Data is provided to allow customization of the bubble content
                      # For more information about the XML format, see
                      # http://simile.mit.edu/wiki/How_to_Create_Event_Source_Files
                      'isDuration': 'false',
                      'start': time.strftime("%a %b %d %Y %H:%M:%S "+self.get_gmtstring(), time.gmtime(date)),
                      'title': title,
                      'data': {'kind': kind,
                               'title': title,
                               'href': href,
                               'author': author or 'anonymous',
                               'date': format_date(date),
                               'time': format_time(date, '%H:%M'),
                               'dateuid': int(date),
                               'message': message},
                      'debug': isinstance(title, Markup),
                    })
            #except Exception, e: # cope with a failure of that provider
            #    pass

        self.req.hdf['events'] = events
Пример #37
0
 def test_sanitize_remove_script_elem(self):
     markup = Markup('<script>alert("Foo")</script>')
     self.assertEquals('', markup.sanitize())
     markup = Markup('<SCRIPT SRC="http://example.com/"></SCRIPT>')
     self.assertEquals('', markup.sanitize())
     markup = Markup('<SCR\0IPT>alert("foo")</SCR\0IPT>')
     self.assertRaises(HTMLParseError, markup.sanitize)
     markup = Markup('<SCRIPT&XYZ SRC="http://example.com/"></SCRIPT>')
     self.assertRaises(HTMLParseError, markup.sanitize)
Пример #38
0
 def trac_get_reference(rawtext, target, text):
     fulltext = text and target+' '+text or target
     link = wiki_to_link(fulltext, self.env, req)
     uri = None
     missing = False
     if isinstance(link, Element):
         linktext = Markup(link).striptags()
         # the following is a bit hackish, but it takes into account:
         #  - an eventual trailing '?' for missing wiki pages
         #  - space eventually introduced due to split_page_names option
         if linktext.rstrip('?').replace(' ', '') != target:
             text = linktext
         uri = link.attr.get('href', '')
         missing = 'missing' in link.attr.get('class_', '')
     else:
         uri = req.href.wiki(target)
         missing = not WikiSystem(self.env).has_page(target)
     if uri:                    
         reference = nodes.reference(rawtext, text or target)
         reference['refuri']= uri
         if missing:
             reference.set_class('missing')
         return reference
     return None
Пример #39
0
def get_changes(env, repos, revs, full=None, req=None, format=None):
    db = env.get_db_cnx()
    changes = {}
    for rev in revs:
        try:
            changeset = repos.get_changeset(rev)
        except NoSuchChangeset:
            changes[rev] = {}
            continue

        wiki_format = env.config['changeset'].getbool('wiki_format_messages')
        message = changeset.message or '--'
        absurls = (format == 'rss')
        if wiki_format:
            shortlog = wiki_to_oneliner(message, env, db,
                                        shorten=True, absurls=absurls)
        else:
            shortlog = Markup.escape(shorten_line(message))

        if full:
            if wiki_format:
                message = wiki_to_html(message, env, req, db,
                                       absurls=absurls, escape_newlines=True)
            else:
                message = html.PRE(message)
        else:
            message = shortlog

        if format == 'rss':
            if isinstance(shortlog, Markup):
                shortlog = shortlog.plaintext(keeplinebreaks=False)
            message = unicode(message)

        changes[rev] = {
            'date_seconds': changeset.date,
            'date': format_datetime(changeset.date),
            'age': pretty_timedelta(changeset.date),
            'author': changeset.author or 'anonymous',
            'message': message, 'shortlog': shortlog,
        }
    return changes
Пример #40
0
 def test_sanitize_remove_onclick_attr(self):
     markup = Markup('<div onclick=\'alert("foo")\' />')
     self.assertEquals('<div></div>', markup.sanitize())
Пример #41
0
 def test_sanitize_invalid_entity(self):
     markup = Markup('&junk;')
     self.assertEquals('&amp;junk;', markup.sanitize())
Пример #42
0
 def test_sanitize_close_empty_tag(self):
     markup = Markup('<a href="#">fo<br>o</a>')
     self.assertEquals('<a href="#">fo<br />o</a>', markup.sanitize())
Пример #43
0
 def test_sanitize_remove_src_javascript(self):
     markup = Markup('<img src=\'javascript:alert("foo")\'>')
     self.assertEquals('<img />', markup.sanitize())
     # Case-insensitive protocol matching
     markup = Markup('<IMG SRC=\'JaVaScRiPt:alert("foo")\'>')
     self.assertEquals('<img />', markup.sanitize())
     # Grave accents (not parsed)
     markup = Markup('<IMG SRC=`javascript:alert("RSnake says, \'foo\'")`>')
     self.assertRaises(HTMLParseError, markup.sanitize)
     # Protocol encoded using UTF-8 numeric entities
     markup = Markup('<IMG SRC=\'&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;'
                     '&#112;&#116;&#58;alert("foo")\'>')
     self.assertEquals('<img />', markup.sanitize())
     # Protocol encoded using UTF-8 numeric entities without a semicolon
     # (which is allowed because the max number of digits is used)
     markup = Markup('<IMG SRC=\'&#0000106&#0000097&#0000118&#0000097'
                     '&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116'
                     '&#0000058alert("foo")\'>')
     self.assertEquals('<img />', markup.sanitize())
     # Protocol encoded using UTF-8 numeric hex entities without a semicolon
     # (which is allowed because the max number of digits is used)
     markup = Markup('<IMG SRC=\'&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69'
                     '&#x70&#x74&#x3A;alert("foo")\'>')
     self.assertEquals('<img />', markup.sanitize())
     # Embedded tab character in protocol
     markup = Markup('<IMG SRC=\'jav\tascript:alert("foo");\'>')
     self.assertEquals('<img />', markup.sanitize())
     # Embedded tab character in protocol, but encoded this time
     markup = Markup('<IMG SRC=\'jav&#x09;ascript:alert("foo");\'>')
     self.assertEquals('<img />', markup.sanitize())
Пример #44
0
 def test_unescape_markup(self):
     string = '<b>"&"</b>'
     markup = Markup.escape(string)
     assert isinstance(markup, Markup)
     self.assertEquals(string, unescape(markup))
Пример #45
0
 def test_sanitize_unchanged(self):
     markup = Markup('<a href="#">fo<br />o</a>')
     self.assertEquals('<a href="#">fo<br />o</a>', markup.sanitize())
Пример #46
0
 def test_sanitize_escape_attr(self):
     markup = Markup('<div title="&lt;foo&gt;"></div>')
     self.assertEquals('<div title="&lt;foo&gt;"></div>', markup.sanitize())
Пример #47
0
 def test_sanitize_entityref_text(self):
     markup = Markup('<a href="#">fo&ouml;</a>')
     self.assertEquals(u'<a href="#">foö</a>', markup.sanitize())
Пример #48
0
 def test_sanitize_escape_text(self):
     markup = Markup('<a href="#">fo&amp;</a>')
     self.assertEquals('<a href="#">fo&amp;</a>', markup.sanitize())
     markup = Markup('<a href="#">&lt;foo&gt;</a>')
     self.assertEquals('<a href="#">&lt;foo&gt;</a>', markup.sanitize())