Exemplo n.º 1
0
 def test_find_element_with_tag(self):
     frag = tag(tag.p('Paragraph with a ',
                tag.a('link', href='http://www.edgewall.org'),
                ' and some ', tag.strong('strong text')))
     self.assertIsNotNone(find_element(frag, tag='p'))
     self.assertIsNotNone(find_element(frag, tag='a'))
     self.assertIsNotNone(find_element(frag, tag='strong'))
     self.assertIsNone(find_element(frag, tag='input'))
     self.assertIsNone(find_element(frag, tag='textarea'))
Exemplo n.º 2
0
 def test_find_element_with_tag(self):
     frag = tag(tag.p('Paragraph with a ',
                tag.a('link', href='http://www.edgewall.org'),
                ' and some ', tag.strong('strong text')))
     self.assertIsNotNone(find_element(frag, tag='p'))
     self.assertIsNotNone(find_element(frag, tag='a'))
     self.assertIsNotNone(find_element(frag, tag='strong'))
     self.assertIsNone(find_element(frag, tag='input'))
     self.assertIsNone(find_element(frag, tag='textarea'))
Exemplo n.º 3
0
 def _check_quickjump(self, req, kwd):
     """Look for search shortcuts"""
     # pylint: disable=maybe-no-member
     noquickjump = int(req.args.get('noquickjump', '0'))
     # 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
         base_path = req.base_path.replace('@', '%40')
         redirect_href = quickjump_href.replace('@', '%40')
         if not redirect_href.startswith(base_path or '/'):
             noquickjump = True
         if noquickjump:
             return {'href': quickjump_href, 'name': tag.EM(name),
                     'description': description}
         else:
             req.redirect(quickjump_href)
Exemplo n.º 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
Exemplo n.º 5
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)
Exemplo n.º 6
0
 def expand(match):
     attrib, wiki_text = match.groups()  # "URL" or "href", "TracLink"
     link = extract_link(self.env, context, wiki_text)
     link = find_element(link, 'href')
     if link:
         href = link.attrib.get('href')
         name = link.children
         description = link.attrib.get('title', '')
     else:
         href = wiki_text
         description = None
         if self.sanitizer:
             href = ''
     attribs = []
     if href:
         if out_format == 'svg':
             format = '="javascript:window.parent.location.href=\'%s\'"'
         else:
             format = '="%s"'
         attribs.append(attrib + format % href)
     if description:
         attribs.append(
             'tooltip="%s"' %
             (description.replace('"', '').replace('\n', '')))
     return '\n'.join(attribs)
Exemplo n.º 7
0
def tracwiki_link(context, value):
     elt = link_parser.extract_link(value.strip(), context)
     elt = html.find_element(elt, 'href')
     if elt is not None:
         return elt.attrib.get('href')
     else:
         return value
Exemplo n.º 8
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
Exemplo n.º 9
0
 def _check_quickjump(self, req, kwd):
     """Look for search shortcuts"""
     noquickjump = as_int(req.args.get('noquickjump'), 0)
     # 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:
             req.redirect(quickjump_href)
Exemplo n.º 10
0
 def process_request(self, req):
     link = req.args.get('link', '')
     parts = link.split(':', 1)
     if len(parts) > 1:
         resolver, target = parts
         if target[:1] + target[-1:] not in ('""', "''"):
             link = '%s:"%s"' % (resolver, target)
     from trac.web.chrome import web_context
     link_frag = extract_link(self.env, web_context(req), link)
     if isinstance(link_frag, (Element, Fragment)):
         elt = find_element(link_frag, 'href')
         if elt is None: # most probably no permissions to view
             raise PermissionError(_("Can't view %(link)s:", link=link))
         href = elt.attrib.get('href')
     else:
         href = req.href(link.rstrip(':'))
     req.redirect(href)
Exemplo n.º 11
0
 def process_request(self, req):
     link = req.args.get('link', '')
     parts = link.split(':', 1)
     if len(parts) > 1:
         resolver, target = parts
         if target[:1] + target[-1:] not in ('""', "''"):
             link = '%s:"%s"' % (resolver, target)
     from trac.web.chrome import web_context
     link_frag = extract_link(self.env, web_context(req), link)
     if isinstance(link_frag, (Element, Fragment)):
         elt = find_element(link_frag, 'href')
         if elt is None:  # most probably no permissions to view
             raise PermissionError(_("Can't view %(link)s:", link=link))
         href = elt.attrib.get('href')
     else:
         href = req.href(link.rstrip(':'))
     req.redirect(href)
Exemplo n.º 12
0
 def expand(match):
     attrib, wiki_text = match.groups() # "URL" or "href", "TracLink"
     link = extract_link(self.env, context, wiki_text)
     link = find_element(link, 'href')
     if link:
         href = link.attrib.get('href')
         name = link.children
         description = link.attrib.get('title', '')
     else:
         href = wiki_text
         description = None
         if self.sanitizer:
             href = ''
     attribs = []
     if href:
         if out_format == 'svg':
             format = '="javascript:window.parent.location.href=\'%s\'"'
         else:
             format = '="%s"'
         attribs.append(attrib + format % href)
     if description:
         attribs.append('tooltip="%s"' % (description.replace('"', '')
                                          .replace('\n', '')))
     return '\n'.join(attribs)
Exemplo n.º 13
0
 def _check_quickjump(self, req, kwd):
     """Look for search shortcuts"""
     noquickjump = int(req.args.get("noquickjump", "0"))
     # 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:
             req.redirect(quickjump_href)
Exemplo n.º 14
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = content.split(',')
        if len(args) == 0:
            raise Exception("No argument.")
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = stripws(args.pop(0))

        # style information
        size_re = re.compile('[0-9]+(%|px)?$')
        attr_re = re.compile('(align|valign|border|width|height|alt'
                             '|margin(?:-(?:left|right|top|bottom))?'
                             '|title|longdesc|class|id|usemap)=(.+)')
        quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$")
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [res[0] for res in
                             BrowserModule(self.env).get_link_resolvers()]
        except Exception:
            browser_links = []
        while args:
            arg = args.pop(0).strip()
            if size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and \
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = quoted_re.search(val) # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val # will be used as a __call__ kwd

        # parse filespec argument to get realm and id if contained.
        parts = filespec.split(':')
        url = raw_url = desc = None
        attachment = None
        if (parts and parts[0] in ('http', 'https', 'ftp')): # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):        # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:                 # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:   # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else: # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1: # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError('No filespec given')
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env, attachment, formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound, e:
                raw_url = formatter.href.chrome('common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
Exemplo n.º 15
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = [stripws(arg) for arg
                             in self._split_args_re.split(content)[1::2]]
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = args.pop(0)

        # style information
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [res[0] for res in
                             BrowserModule(self.env).get_link_resolvers()]
        except Exception:
            browser_links = []
        while args:
            arg = args.pop(0)
            if self._size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = self._attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = self._quoted_re.search(val)  # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val  # will be used as a __call__ kwd

        if self._quoted_re.match(filespec):
            filespec = filespec.strip('\'"')
        # parse filespec argument to get realm and id if contained.
        parts = [i.strip('''['"]''')
                 for i in self._split_filespec_re.split(filespec)[1::2]]
        url = raw_url = desc = None
        attachment = None
        if parts and parts[0] in ('http', 'https', 'ftp', 'data'):  # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):        # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:                 # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:  # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else:  # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                elif id == 'shared':
                    raw_url = url = formatter.href.chrome('shared', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1:  # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError(_("No filespec given"))
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env, attachment, formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound:
                raw_url = chrome_resource_path(formatter.context.req,
                                               'common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
        for key in ('title', 'alt'):
            if desc and key not in attr:
                attr[key] = desc
        if style:
            attr['style'] = '; '.join('%s:%s' % (k, escape(v))
                                      for k, v in style.iteritems())
        result = tag.img(src=raw_url, **attr)
        if link is not None:
            result = tag.a(result, href=link or url,
                           style='padding:0; border:none')
        return result
Exemplo n.º 16
0
    def expand_macro(self, formatter, name, content):
        args = None
        if content:
            content = stripws(content)
            # parse arguments
            # we expect the 1st argument to be a filename (filespec)
            args = [stripws(arg) for arg
                                 in self._split_args_re.split(content)[1::2]]
        if not args:
            return ''
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = args.pop(0)

        # style information
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [res[0] for res in
                             BrowserModule(self.env).get_link_resolvers()]
        except Exception:
            browser_links = []
        while args:
            arg = args.pop(0)
            if self._size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = self._attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % _arg_as_int(val, key, min=1)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % _arg_as_int(val, key, min=1)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % _arg_as_int(val, key)
                    else:
                        m = self._quoted_re.search(val)  # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val  # will be used as a __call__ kwd

        if self._quoted_re.match(filespec):
            filespec = filespec.strip('\'"')
        # parse filespec argument to get realm and id if contained.
        parts = [i.strip('\'"')
                 for i in self._split_filespec_re.split(filespec)[1::2]]
        realm = parts[0] if parts else None
        url = raw_url = desc = None
        attachment = None
        interwikimap = InterWikiMap(self.env)
        if realm in ('http', 'https', 'ftp', 'data'):  # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif realm in interwikimap:
            url, desc = interwikimap.url(realm, ':'.join(parts[1:]))
            raw_url = url
        elif filespec.startswith('//'):       # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):        # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:                 # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:  # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename, rev=rev,
                                                 format='raw')
                desc = filespec
            else:  # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                elif id == 'shared':
                    raw_url = url = formatter.href.chrome('shared', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm, id).child('attachment',
                                                           filename)
        elif len(parts) == 1:  # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            return system_message(_("No filespec given"))
        if attachment:
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound:
                link = None
                raw_url = chrome_resource_path(formatter.context.req,
                                               'common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
            else:
                if 'ATTACHMENT_VIEW' in formatter.perm(attachment):
                    url = get_resource_url(self.env, attachment,
                                           formatter.href)
                    raw_url = get_resource_url(self.env, attachment,
                                               formatter.href, format='raw')

        for key in ('title', 'alt'):
            if desc and key not in attr:
                attr[key] = desc
        if style:
            attr['style'] = '; '.join('%s:%s' % (k, escape(v))
                                      for k, v in style.iteritems())
        if not WikiSystem(self.env).is_safe_origin(raw_url,
                                                   formatter.context.req):
            attr['crossorigin'] = 'anonymous'  # avoid password prompt
        result = tag.img(src=raw_url, **attr)
        if link is not None:
            result = tag.a(result, href=link or url,
                           style='padding:0; border:none')
        return result
Exemplo n.º 17
0
    def expand_macro(self, formatter, name, content):
        # args will be null if the macro is called without parenthesis.
        if not content:
            return ''
        # parse arguments
        # we expect the 1st argument to be a filename (filespec)
        args = content.split(',')
        if len(args) == 0:
            raise Exception("No argument.")
        # strip unicode white-spaces and ZWSPs are copied from attachments
        # section (#10668)
        filespec = stripws(args.pop(0))

        # style information
        size_re = re.compile('[0-9]+(%|px)?$')
        attr_re = re.compile('(align|valign|border|width|height|alt'
                             '|margin(?:-(?:left|right|top|bottom))?'
                             '|title|longdesc|class|id|usemap)=(.+)')
        quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$")
        attr = {}
        style = {}
        link = ''
        # helper for the special case `source:`
        #
        from trac.versioncontrol.web_ui import BrowserModule
        # FIXME: somehow use ResourceSystem.get_known_realms()
        #        ... or directly trac.wiki.extract_link
        try:
            browser_links = [
                res[0] for res in BrowserModule(self.env).get_link_resolvers()
            ]
        except Exception:
            browser_links = []
        while args:
            arg = stripws(args.pop(0))
            if size_re.match(arg):
                # 'width' keyword
                attr['width'] = arg
            elif arg == 'nolink':
                link = None
            elif arg.startswith('link='):
                val = arg.split('=', 1)[1]
                elt = extract_link(self.env, formatter.context, val.strip())
                elt = find_element(elt, 'href')
                link = None
                if elt is not None:
                    link = elt.attrib.get('href')
            elif arg in ('left', 'right'):
                style['float'] = arg
            elif arg == 'center':
                style['margin-left'] = style['margin-right'] = 'auto'
                style['display'] = 'block'
                style.pop('margin', '')
            elif arg in ('top', 'bottom', 'middle'):
                style['vertical-align'] = arg
            else:
                match = attr_re.match(arg)
                if match:
                    key, val = match.groups()
                    if (key == 'align' and
                            val in ('left', 'right', 'center')) or \
                        (key == 'valign' and \
                            val in ('top', 'middle', 'bottom')):
                        args.append(val)
                    elif key in ('margin-top', 'margin-bottom'):
                        style[key] = ' %dpx' % int(val)
                    elif key in ('margin', 'margin-left', 'margin-right') \
                             and 'display' not in style:
                        style[key] = ' %dpx' % int(val)
                    elif key == 'border':
                        style['border'] = ' %dpx solid' % int(val)
                    else:
                        m = quoted_re.search(val)  # unquote "..." and '...'
                        if m:
                            val = m.group(1)
                        attr[str(key)] = val  # will be used as a __call__ kwd

        # parse filespec argument to get realm and id if contained.
        parts = [
            i.strip('''['"]''')
            for i in self._split_filespec_re.split(filespec)
        ]
        url = raw_url = desc = None
        attachment = None
        if (parts and parts[0] in ('http', 'https', 'ftp')):  # absolute
            raw_url = url = filespec
            desc = url.rsplit('?')[0]
        elif filespec.startswith('//'):  # server-relative
            raw_url = url = filespec[1:]
            desc = url.rsplit('?')[0]
        elif filespec.startswith('/'):  # project-relative
            params = ''
            if '?' in filespec:
                filespec, params = filespec.rsplit('?', 1)
            url = formatter.href(filespec)
            if params:
                url += '?' + params
            raw_url, desc = url, filespec
        elif len(parts) == 3:  # realm:id:attachment-filename
            #                                 # or intertrac:realm:id
            realm, id, filename = parts
            intertrac_target = "%s:%s" % (id, filename)
            it = formatter.get_intertrac_url(realm, intertrac_target)
            if it:
                url, desc = it
                raw_url = url + unicode_quote('?format=raw')
            else:
                attachment = Resource(realm, id).child('attachment', filename)
        elif len(parts) == 2:
            realm, filename = parts
            if realm in browser_links:  # source:path
                # TODO: use context here as well
                rev = None
                if '@' in filename:
                    filename, rev = filename.rsplit('@', 1)
                url = formatter.href.browser(filename, rev=rev)
                raw_url = formatter.href.browser(filename,
                                                 rev=rev,
                                                 format='raw')
                desc = filespec
            else:  # #ticket:attachment or WikiPage:attachment
                # FIXME: do something generic about shorthand forms...
                realm = None
                id, filename = parts
                if id and id[0] == '#':
                    realm = 'ticket'
                    id = id[1:]
                elif id == 'htdocs':
                    raw_url = url = formatter.href.chrome('site', filename)
                    desc = os.path.basename(filename)
                elif id == 'shared':
                    raw_url = url = formatter.href.chrome('shared', filename)
                    desc = os.path.basename(filename)
                else:
                    realm = 'wiki'
                if realm:
                    attachment = Resource(realm,
                                          id).child('attachment', filename)
        elif len(parts) == 1:  # it's an attachment of the current resource
            attachment = formatter.resource.child('attachment', filespec)
        else:
            raise TracError('No filespec given')
        if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
            url = get_resource_url(self.env, attachment, formatter.href)
            raw_url = get_resource_url(self.env,
                                       attachment,
                                       formatter.href,
                                       format='raw')
            try:
                desc = get_resource_summary(self.env, attachment)
            except ResourceNotFound as e:
                raw_url = formatter.href.chrome('common/attachment.png')
                desc = _('No image "%(id)s" attached to %(parent)s',
                         id=attachment.id,
                         parent=get_resource_name(self.env, attachment.parent))
        for key in ('title', 'alt'):
            if desc and not key in attr:
                attr[key] = desc
        if style:
            attr['style'] = '; '.join('%s:%s' % (k, escape(v))
                                      for k, v in style.iteritems())
        result = tag.img(src=raw_url, **attr)
        if link is not None:
            result = tag.a(result,
                           href=link or url,
                           style='padding:0; border:none')
        return result