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
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)
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: link = extract_link(self.env, Context.from_request(req, 'search'), kwd) if isinstance(link, Element): 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)
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)
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) def get_first_href(item): """Depth-first search for the first `href` attribute.""" if isinstance(item, Element): href = item.attrib.get('href') if href is not None: return href if isinstance(item, Fragment): for each in item.children: href = get_first_href(each) if href is not None: return href if isinstance(link_frag, (Element, Fragment)): href = get_first_href(link_frag) if href is None: # most probably no permissions to view raise PermissionError(_("Can't view %(link)s:", link=link)) else: href = req.href(link.rstrip(':')) req.redirect(href)
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: link = extract_link(self.env, Context.from_request(req, 'search'), kwd) if isinstance(link, Element): 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)
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)
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)
def process_request(self, req): link = req.args.get("link", "") parts = link.split(":", 1) if len(parts) > 1: resolver, target = parts if target and (target[0] not in "'\"" or target[0] != target[-1]): link = '%s:"%s"' % (resolver, target) link_frag = extract_link(self.env, Context.from_request(req), link) def get_first_href(item): """Depth-first search for the first `href` attribute.""" if isinstance(item, Element): href = item.attrib.get("href") if href is not None: return href if isinstance(item, Fragment): for each in item.children: href = get_first_href(each) if href is not None: return href if isinstance(link_frag, (Element, Fragment)): href = get_first_href(link_frag) if href is None: # most probably no permissions to view raise PermissionError(_("Can't view %(link)s:", link=link)) else: href = req.href(link.rstrip(":")) req.redirect(href)
def process_request(self, req): link = req.args.get('link', '') link_elt = extract_link(self.env, Context.from_request(req), link) if isinstance(link_elt, Element): href = link_elt.attrib.get('href') if href is None: # most probably no permissions to view raise PermissionError(_("Can't view %(link)s:", link=link)) else: href = req.href(link.rstrip(':')) req.redirect(href)
def _get_quickjump(self, req, query): """Find quickjump requests if the search comes from the searchbox in the header. The search is assumed to be from the header searchbox if no page or per_page arguments are found. """ if req.args.get('page') or req.args.get('per_page'): return None link = extract_link(self.env, Context.from_request(req, 'advsearch'), query) if isinstance(link, Element): return link.attrib.get('href')
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)
def expand(match): wiki_text = match.groups()[0] # TracLink ([1], source:file/, ...) link = extract_link(self.env, context, wiki_text) if isinstance(link, Element): href = link.attrib.get('href') name = link.children description = link.attrib.get('title', '') else: href = wiki_text description = None if out_format == 'svg': format = 'URL="javascript:window.parent.location.href=\'%s\'"' else: format = 'URL="%s"' url = format % href if description: url += '\ntooltip="%s"' % description \ .replace('"', '').replace('\n', '') return url
def expand(match): wiki_text = match.groups()[0] # TracLink ([1], source:file/, ...) link = extract_link(self.env, formatter.context, wiki_text) if isinstance(link, Element): href = link.attrib.get('href') name = link.children description = link.attrib.get('title', '') else: href = wiki_text description = None if out_format == 'svg': format = 'URL="javascript:window.parent.location.href=\'%s\'"' else: format = 'URL="%s"' url = format % href if description: url += '\ntooltip="%s"' % description \ .replace('"', '').replace('\n', '') return url
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)
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)
def get_absolute_url(url, formatter=None, base=None): """ Generate an absolute url from the url with the special schemes {htdocs,chrome,ticket,wiki,source} simply return the url if given with {http,https,ftp} schemes. Also supports TracLinks. Examples: http://example.com/filename.ext ie. http://www.google.com/logo.jpg htdocs://site/filename.ext htdocs://plugin/dir/filename.ext note: `chrome` is an alias for `htdocs` ticket://number/attachment.pdf ie. ticket://123/specification.pdf wiki://WikiWord/attachment.jpg source://changeset/path/filename.ext ie. source://1024/trunk/docs/README """ def ujoin(*parts): """ Remove double slashes. """ parts = [part.strip('/') for part in parts] return '/' + '/'.join(parts) # You must supply a formatter or a base. if not base: base = formatter.href.base if url.find('://') > 0: scheme, netloc, path, query, params, fragment = urlparse.urlparse(url) if scheme in ('ftp', 'http', 'https'): return url if scheme in ('htdocs', 'chrome'): return ujoin(base, 'chrome', path) if scheme in ('source', ): return ujoin(base, 'export', path) if scheme in ('ticket', ): return ujoin(base, 'raw-attachment/ticket', path) if scheme in ('wiki', ): return ujoin(base, 'raw-attachment/wiki', path) return url # You'll need a formatter for this, code from #3938, serious testing needed. else: link = extract_link(formatter.env, formatter.context, url) if isinstance(link, Element): url = link.attrib.get('href') scheme, netloc, path, query, params, fragment = urlparse.urlparse( url) if path.startswith('/browser/'): query_dict = xform_query(query) query_dict['format'] = 'raw' query = xfrom_query(query_dict) url = urlparse.urlunparse( (scheme, netloc, path, query, params, fragment)) elif path.startswith('/attachement/'): url = url.replace('/attachment/', '/raw-attachment/', 1) return url
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.") filespec = 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 = '' 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()) link = None if isinstance(elt, Element): 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 = desc = filespec elif filespec.startswith('//'): # server-relative raw_url = url = desc = filespec[1:] elif filespec.startswith('/'): # project-relative # use href, but unquote to allow args (use default html escaping) raw_url = url = desc = unquote(formatter.href(filespec)) elif len(parts) == 3: # realm:id:attachment-filename realm, id, filename = parts attachment = Resource(realm, id).child('attachment', filename) elif len(parts) == 2: # FIXME: somehow use ResourceSystem.get_known_realms() # ... or directly trac.wiki.extract_link from trac.versioncontrol.web_ui import BrowserModule try: browser_links = [res[0] for res in BrowserModule(self.env).get_link_resolvers()] except Exception: browser_links = [] if parts[0] in browser_links: # source:path # TODO: use context here as well realm, filename = parts rev = None if '@' in filename: filename, rev = filename.split('@') 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))
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
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.") filespec = args[0] # style information size_re = re.compile('[0-9]+(%|px)?$') attr_re = re.compile('(align|border|width|height|alt' '|title|longdesc|class|id|usemap)=(.+)') quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$") attr = {} style = {} link = '' for arg in args[1:]: arg = arg.strip() if size_re.match(arg): # 'width' keyword attr['width'] = arg continue if arg == 'nolink': link = None continue if arg.startswith('link='): val = arg.split('=', 1)[1] elt = extract_link(self.env, formatter.context, val.strip()) link = None if isinstance(elt, Element): link = elt.attrib.get('href') continue if arg in ('left', 'right', 'top', 'bottom'): style['float'] = arg continue match = attr_re.match(arg) if match: key, val = match.groups() m = quoted_re.search(val) # unquote "..." and '...' if m: val = m.group(1) if key == 'align': style['float'] = val elif key == 'border': style['border'] = ' %dpx solid' % int(val); else: attr[str(key)] = val # will be used as a __call__ keyword # 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 = desc = filespec elif filespec.startswith('//'): # server-relative raw_url = url = desc = filespec[1:] elif filespec.startswith('/'): # project-relative # use href, but unquote to allow args (use default html escaping) raw_url = url = desc = unquote(formatter.href(filespec)) elif len(parts) == 3: # realm:id:attachment-filename realm, id, filename = parts attachment = Resource(realm, id).child('attachment', filename) elif len(parts) == 2: # FIXME: somehow use ResourceSystem.get_known_realms() # ... or directly trac.wiki.extract_link from trac.versioncontrol.web_ui import BrowserModule try: browser_links = [res[0] for res in BrowserModule(self.env).get_link_resolvers()] except Exception: browser_links = [] if parts[0] in browser_links: # source:path # TODO: use context here as well realm, filename = parts rev = None if '@' in filename: filename, rev = filename.split('@') 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') desc = get_resource_summary(self.env, attachment) 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
def extract_url(env, context, wikilink, raw=False): """ = Description for `extract_url()` = Extracts an URL from an Wiki link, e.g. to used in macro produced HTML code. Website: http://trac-hacks.org/wiki/ExtractUrlPlugin `$Id$` == Description == Returns an (possible relative) URL which can be used in HTML code. If `raw` is true the returned link will point to a downloadable version of the linked resource otherwise the same link is returned which would be used in the resulting Wiki page. The raw links are also usable as online resouces, e.g. if the link target is to be used as input for a flash application etc. == Usage == General: {{{ from tracextracturl import extract_url # ... url = extract_url (env, context, wikilink, raw=False) }}} Inside WikiMacros: {{{ #!python from tracextracturl import extract_url def MyMacro(WikiMacroBase): def expand_macro (self, formatter, name, content): # e.g. wikilink = 'wiki:WikiStart' or 'attachment:file.ext' url = extract_url(self.env, formatter.context, wikilink) rawurl = extract_url(self.env, formatter.context, wikilink, True) }}} == Example == Inside a Trac macro called from the wiki page 'ExamplePage' of project 'project1' on a multi-project trac server: {{{ extract_url(self.env, formatter, 'attachment:file.js', True) }}} will return `/project1/raw-attachment/wiki/ExamplePage/file.js`, which could be directly accessed by the browser inside some javascript or flash HTML object code produced by the macro. """ from genshi.builder import Element, Fragment from trac.wiki.formatter import extract_link if not wikilink: return '' link = extract_link(env, context, '[' + wikilink + ' x]') #env.log.debug("link = " + str(link.__class__) + ' ' + str(link)) if isinstance(link, Element): href = link.attrib.get('href') #env.log.debug("href1 = " + href) elif isinstance(link, Fragment): link = link.children[0] href = link.attrib.get('href') #env.log.debug("href2 = " + href) else: href = None if not href: return '' if raw: # rewrite URL to point to downloadable/exportable/raw version of the # linked resource # Remove existing project URL part for later string search base_path = context.req.base_path if base_path and href.startswith(base_path): # href relative to base path rhref = href[len(base_path):] else: rhref = href # For browser links add the 'format=raw' URL parameter. # The alternative '/export' target isn't used because a revision number # would be needed. if rhref.startswith('/browser/'): if rhref.find('?') == -1: # If no other parameter exists, simply append: href += r'?format=raw' else: # Otherwise add to existing parameters if this one doesn't # exists yet: if href.find(r'?format=') == -1 and href.find( r'&format=') == -1: href += r'&format=raw' # Change 'attachment' links to 'raw-attachment' links: elif rhref.startswith('/attachment/'): href = href.replace('/attachment/', '/raw-attachment/', 1) # All other link types should be already fine for file export (if # applicable) return href
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.") filespec = args[0] # style information size_re = re.compile('[0-9]+(%|px)?$') attr_re = re.compile('(align|border|width|height|alt' '|title|longdesc|class|id|usemap)=(.+)') quoted_re = re.compile("(?:[\"'])(.*)(?:[\"'])$") layers_re = re.compile("^[0-9]+(\.[0-9]+)*$") attr = {} style = {} link = '' width = None layers = None for arg in args[1:]: arg = arg.strip() if size_re.match(arg): if width: raise Exception("Argument 'width' appears more than once.") width = arg attr['width'] = arg continue if arg == 'nolink': link = None continue if arg.startswith('link='): val = arg.split('=', 1)[1] elt = extract_link(self.env, formatter.context, val.strip()) link = None if isinstance(elt, Element): link = elt.attrib.get('href') continue if arg in ('left', 'right', 'top', 'bottom'): style['float'] = arg continue if arg.startswith('layers='): if layers: raise Exception("Argument 'layers' appears more than once.") layers = arg.split('=', 1)[1] if not layers_re.match(layers): raise Exception("Wrong layer list format, use dot separated list of integer numbers.") match = attr_re.match(arg) if match: key, val = match.groups() m = quoted_re.search(val) # unquote "..." and '...' if m: val = m.group(1) if key == 'align': style['float'] = val elif key == 'border': style['border'] = ' %dpx solid' % int(val); else: attr[str(key)] = val # will be used as a __call__ keyword # Got the args now do some processing attachment = formatter.resource.child('attachment', filespec) realm = formatter.resource.realm resource_id = formatter.resource.id # The use of "id" could cause a conflict? if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment): url = get_resource_url(self.env, attachment, formatter.href) description = get_resource_summary(self.env, attachment) # Includes vdx for use with Visio png_url = url.replace(".dia",".png").replace(".vdx",".png") dia_attachment = Attachment(self.env, realm, resource_id, filespec) dia_path = dia_attachment.path dia_filename = dia_attachment.filename png_path = dia_path.replace('.dia','.png').replace(".vdx",".png") png_filename = dia_filename.replace('.dia','.png').replace(".vdx",".png") # the layers are encoded into the path as dot-separated list, e.g. basename.1.2.png if layers: layers_extension = '.' + layers + '.png' png_path = png_path.replace('.png', layers_extension) png_filename = png_filename.replace('.png', layers_extension) png_url = png_url.replace(".png", layers_extension) png_attachment = Attachment(self.env, realm, resource_id, filespec) if len(description) <= 0: description = 'PNG render of ' + dia_filename self.env.log.info('Getting file modification times.') try: dia_mtime = os.path.getmtime(dia_path) except Exception: raise Exception('File does not exist: %s', dia_path) try: png_mtime = os.path.getmtime(png_path) except Exception: png_mtime = 0 else: try: im = Image.open(png_path) except Exception, e: self.env.log.info('Error checking original png file width for Dia = %s',e) raise Exception('Error checking original png file width for Dia.') existing_width = im.size[0]
def expand_macro(self, formatter, name, content, args=None): content = content.replace('\n', ',') largs, kwargs = parse_args(content, multi=['marker', 'to']) if len(largs) > 0: arg = unicode(largs[0]) if _reCOORDS.match(arg): if not 'center' in kwargs: kwargs['center'] = arg else: if not 'address' in kwargs: kwargs['address'] = arg if 'from' in kwargs and not 'address' in kwargs and not 'center' in kwargs: arg = unicode(kwargs['from']) if _reCOORDS.match(arg): if not 'center' in kwargs: kwargs['center'] = arg else: if not 'address' in kwargs: kwargs['address'] = arg # Check if Google API key is set (if not the Google Map script file # wasn't inserted by `post_process_request` and the map wont load) if not self.api_key: raise TracError( "No Google Maps API key given! Tell your web admin to get one at http://code.google.com/apis/maps/signup.html .\n" ) # Use default values if needed zoom = None size = None try: if 'zoom' in kwargs: zoom = unicode(int(kwargs['zoom'])) else: zoom = unicode(self.default_zoom) except: raise TracError( "Invalid value for zoom given! Please provide an integer from 0 to 19." ) if 'size' in kwargs: size = unicode(kwargs['size']) else: size = unicode(self.default_size) # Set target for hyperlinked markers target = "" if not 'target' in kwargs: kwargs['target'] = self.default_target if kwargs['target'] in ('new', 'newwindow', '_blank'): target = "newwindow" # Get height and width width = None height = None try: if size.find(':') != -1: (width, height) = size.lower().split(':') # Check for correct units: if not width[-2:] in _css_units \ or not height[-2:] in _css_units: raise TracError("Wrong unit(s)!") # The rest must be a number: float(width[:-2]) float(height[:-2]) else: (width, height) = size.lower().split('x') width = str(int(width)) + "px" height = str(int(height)) + "px" except: raise TracError("Invalid value for size given! Please provide " "{width}x{height} in pixels (without unit) or " "{width}{unit}:{height}{unit} in CSS units (%s)." \ % ', '.join(_css_units) ) # Correct separator for 'center' argument because comma isn't allowed in # macro arguments center = "" if 'center' in kwargs: center = unicode(kwargs['center']).replace(':', ',').strip(' "\'') if not _reCOORDS.match(center): raise TracError("Invalid center coordinates given!") # Format address address = "" if 'address' in kwargs: address = self._format_address(kwargs['address']) if self.geocoding_server: coord = self._get_coords(address) center = ",".join(coord[0:2]) address = "" if not 'zoom' in kwargs: zoom = _accuracy_to_zoom[int(coord[2])] # Internal formatting functions: def gtyp(stype): return "G_%s_MAP" % str(stype) def gcontrol(control): return "map.addControl(new G%sControl());\n" % str(control) def gmarker(lat, lng, letter='', link='', title=''): if not title: title = link if not letter: letter = '' else: letter = str(letter).upper() if str(letter).startswith('.'): letter = '' else: letter = letter[0] return "SetMarkerByCoords(map,%s,%s,'%s','%s','%s', '%s');\n" \ % (str(lat),str(lng),letter,str(link),str(title),str(target)) def gmarkeraddr(address, letter='', link='', title=''): if not title: title = link if not letter: letter = '' else: letter = str(letter).upper() if str(letter).startswith('.'): letter = '' else: letter = letter[0] return "SetMarkerByAddress(map,'%s','%s','%s','%s','%s',geocoder);\n" \ % (str(address),letter,str(link),str(title),str(target)) # Set initial map type type = 'NORMAL' types = [] types_str = None if 'types' in kwargs: types = unicode(kwargs['types']).upper().split(':') types_str = ','.join(map(gtyp, types)) type = types[0] if 'type' in kwargs: type = unicode(kwargs['type']).upper() if 'types' in kwargs and not type in types: types_str += ',' + type types.insert(0, type) elif not type in _supported_map_types: type = 'NORMAL' # if types aren't set and a type is set which is supported # but not a default type: if not 'types' in kwargs and type in _supported_map_types and not type in _default_map_types: # enable type (and all default types): types = _default_map_types + [type] types_str = ','.join(map(gtyp, types)) if types_str: types_str = '[' + types_str + ']' else: types_str = 'G_DEFAULT_MAP_TYPES' # Produce controls control_str = "" controls = ['LargeMap', 'MapType'] if 'controls' in kwargs: controls = [] for control in unicode(kwargs['controls']).upper().split(':'): if control in _supported_controls: controls.append(_supported_controls[control]) controls_str = ''.join(map(gcontrol, controls)) # Produce markers markers_str = "" if not 'marker' in kwargs: kwargs['marker'] = [] if 'markers' in kwargs: kwargs['marker'].extend( parse_args(unicode(kwargs['markers']), delim='|', listonly=True)) if kwargs['marker']: markers = [] for marker in kwargs['marker']: location, letter, link, title = parse_args(marker, delim=';', listonly=True, minlen=4)[:4] if not title: title = link # Convert wiki to HTML link: link = extract_link(self.env, formatter.context, link) if isinstance(link, Element): link = link.attrib.get('href') else: link = '' location = self._format_address(location) if _reCOORDS.match(location): coord = location.split(':') markers.append( gmarker(coord[0], coord[1], letter, link, title)) else: if self.geocoding_server: coord = [] if location == 'center': if address: coord = self._get_coords(address) else: coord = center.split(',') else: coord = self._get_coords(location) markers.append( gmarker(coord[0], coord[1], letter, link, title)) else: if location == 'center': if address: markers.append( gmarkeraddr(address, letter, link, title)) else: coord = center.split(',') markers.append( gmarker(coord[0], coord[1], letter, link, title)) else: markers.append( gmarkeraddr(location, letter, link, title)) markers_str = ''.join(markers) # Get macro count from request object req = formatter.req count = getattr(req, COUNT, 0) id = 'tracgooglemap-%s' % count setattr(req, COUNT, count + 1) # Canvas for this map mapdiv = tag.div("Google Map is loading ... (JavaScript enabled?)", id=id, style="width: %s; height: %s;" % (width, height), class_="tracgooglemap") if 'from' in kwargs and 'to' in kwargs: directions = "from: %s to: %s" % (kwargs['from'], ' to: '.join( list(kwargs['to']))) mapnmore = tag.table(tag.tr( tag.td( tag.div("", class_='tracgooglemap-directions', id='tracgooglemap-directions-%s' % count), style="vertical-align:top;", ), tag.td( mapdiv, style="vertical-align:top;", )), class_='tracgooglemaps') else: directions = "" mapnmore = mapdiv # put everything in a tidy div html = tag.div( [ # Initialization script for this map tag.script(Markup( _javascript_code % { 'id': id, 'center': center, 'zoom': zoom, 'address': address, 'type': type, 'width': width, 'height': height, 'types_str': types_str, 'controls_str': controls_str, 'markers_str': markers_str, 'directions': directions, }), type="text/javascript"), mapnmore ], class_="tracgooglemap-parent") return html
def extract_url (env, context, wikilink, raw=False): """ = Description for `extract_url()` = Extracts an URL from an Wiki link, e.g. to used in macro produced HTML code. Website: http://trac-hacks.org/wiki/ExtractUrlPlugin `$Id$` == Description == Returns an (possible relative) URL which can be used in HTML code. If `raw` is true the returned link will point to a downloadable version of the linked resource otherwise the same link is returned which would be used in the resulting Wiki page. The raw links are also usable as online resouces, e.g. if the link target is to be used as input for a flash application etc. == Usage == General: {{{ from tracextracturl import extract_url # ... url = extract_url (env, context, wikilink, raw=False) }}} Inside WikiMacros: {{{ #!python from tracextracturl import extract_url def MyMacro(WikiMacroBase): def expand_macro (self, formatter, name, content): # e.g. wikilink = 'wiki:WikiStart' or 'attachment:file.ext' url = extract_url(self.env, formatter.context, wikilink) rawurl = extract_url(self.env, formatter.context, wikilink, True) }}} == Example == Inside a Trac macro called from the wiki page 'ExamplePage' of project 'project1' on a multi-project trac server: {{{ extract_url(self.env, formatter, 'attachment:file.js', True) }}} will return `/project1/raw-attachment/wiki/ExamplePage/file.js`, which could be directly accessed by the browser inside some javascript or flash HTML object code produced by the macro. """ from genshi.builder import Element, Fragment from trac.wiki.formatter import extract_link if not wikilink: return '' link = extract_link(env, context, '[' + wikilink + ' x]') #env.log.debug("link = " + str(link.__class__) + ' ' + str(link)) if isinstance(link, Element): href = link.attrib.get('href') #env.log.debug("href1 = " + href) elif isinstance(link, Fragment): link = link.children[0] href = link.attrib.get('href') #env.log.debug("href2 = " + href) else: href = None if not href: return '' if raw: # rewrite URL to point to downloadable/exportable/raw version of the # linked resource # Remove existing project URL part for later string search base_path = context.req.base_path if base_path and href.startswith(base_path): # href relative to base path rhref = href[len(base_path):] else: rhref = href # For browser links add the 'format=raw' URL parameter. # The alternative '/export' target isn't used because a revision number # would be needed. if rhref.startswith('/browser/'): if rhref.find('?') == -1: # If no other parameter exists, simply append: href += r'?format=raw' else: # Otherwise add to existing parameters if this one doesn't # exists yet: if href.find(r'?format=') == -1 and href.find(r'&format=') == -1: href += r'&format=raw' # Change 'attachment' links to 'raw-attachment' links: elif rhref.startswith('/attachment/'): href = href.replace('/attachment/','/raw-attachment/', 1) # All other link types should be already fine for file export (if # applicable) return href
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
def expand_macro(self, formatter, name, content, args=None): content = content.replace('\n',',') largs, kwargs = parse_args(content, multi=['marker','to']) if len(largs) > 0: arg = unicode(largs[0]) if _reCOORDS.match(arg): if not 'center' in kwargs: kwargs['center'] = arg else: if not 'address' in kwargs: kwargs['address'] = arg if 'from' in kwargs and not 'address' in kwargs and not 'center' in kwargs: arg = unicode(kwargs['from']) if _reCOORDS.match(arg): if not 'center' in kwargs: kwargs['center'] = arg else: if not 'address' in kwargs: kwargs['address'] = arg # Check if Google API key is set (if not the Google Map script file # wasn't inserted by `post_process_request` and the map wont load) if not self.api_key: raise TracError("No Google Maps API key given! Tell your web admin to get one at http://code.google.com/apis/maps/signup.html .\n") # Use default values if needed zoom = None size = None try: if 'zoom' in kwargs: zoom = unicode( int( kwargs['zoom'] ) ) else: zoom = unicode( self.default_zoom ) except: raise TracError("Invalid value for zoom given! Please provide an integer from 0 to 19.") if 'size' in kwargs: size = unicode( kwargs['size'] ) else: size = unicode( self.default_size ) # Set target for hyperlinked markers target = "" if not 'target' in kwargs: kwargs['target'] = self.default_target if kwargs['target'] in ('new','newwindow','_blank'): target = "newwindow" # Get height and width width = None height = None try: if size.find(':') != -1: (width,height) = size.lower().split(':') # Check for correct units: if not width[-2:] in _css_units \ or not height[-2:] in _css_units: raise TracError("Wrong unit(s)!") # The rest must be a number: float( width[:-2] ) float( height[:-2] ) else: (width,height) = size.lower().split('x') width = str( int( width ) ) + "px" height = str( int( height ) ) + "px" except: raise TracError("Invalid value for size given! Please provide " "{width}x{height} in pixels (without unit) or " "{width}{unit}:{height}{unit} in CSS units (%s)." \ % ', '.join(_css_units) ) # Correct separator for 'center' argument because comma isn't allowed in # macro arguments center = "" if 'center' in kwargs: center = unicode(kwargs['center']).replace(':',',').strip(' "\'') if not _reCOORDS.match(center): raise TracError("Invalid center coordinates given!") # Format address address = "" if 'address' in kwargs: address = self._format_address(kwargs['address']) if self.geocoding_server: coord = self._get_coords(address) center = ",".join(coord[0:2]) address = "" if not 'zoom' in kwargs: zoom = _accuracy_to_zoom[ int( coord[2] ) ] # Internal formatting functions: def gtyp (stype): return "G_%s_MAP" % str(stype) def gcontrol (control): return "map.addControl(new G%sControl());\n" % str(control) def gmarker (lat,lng,letter='',link='',title=''): if not title: title = link if not letter: letter = '' else: letter = str(letter).upper() if str(letter).startswith('.'): letter = '' else: letter = letter[0] return "SetMarkerByCoords(map,%s,%s,'%s','%s','%s', '%s');\n" \ % (str(lat),str(lng),letter,str(link),str(title),str(target)) def gmarkeraddr (address,letter='',link='',title=''): if not title: title = link if not letter: letter = '' else: letter = str(letter).upper() if str(letter).startswith('.'): letter = '' else: letter = letter[0] return "SetMarkerByAddress(map,'%s','%s','%s','%s','%s',geocoder);\n" \ % (str(address),letter,str(link),str(title),str(target)) # Set initial map type type = 'NORMAL' types = [] types_str = None if 'types' in kwargs: types = unicode(kwargs['types']).upper().split(':') types_str = ','.join(map(gtyp,types)) type = types[0] if 'type' in kwargs: type = unicode(kwargs['type']).upper() if 'types' in kwargs and not type in types: types_str += ',' + type types.insert(0, type) elif not type in _supported_map_types: type = 'NORMAL' # if types aren't set and a type is set which is supported # but not a default type: if not 'types' in kwargs and type in _supported_map_types and not type in _default_map_types: # enable type (and all default types): types = _default_map_types + [type] types_str = ','.join(map(gtyp,types)) if types_str: types_str = '[' + types_str + ']' else: types_str = 'G_DEFAULT_MAP_TYPES' # Produce controls control_str = "" controls = ['LargeMap','MapType'] if 'controls' in kwargs: controls = [] for control in unicode(kwargs['controls']).upper().split(':'): if control in _supported_controls: controls.append( _supported_controls[control] ) controls_str = ''.join(map(gcontrol,controls)) # Produce markers markers_str = "" if not 'marker' in kwargs: kwargs['marker'] = [] if 'markers' in kwargs: kwargs['marker'].extend( parse_args( unicode(kwargs['markers']), delim='|', listonly=True) ) if kwargs['marker']: markers = [] for marker in kwargs['marker']: location, letter, link, title = parse_args( marker, delim=';', listonly=True, minlen=4 )[:4] if not title: title = link # Convert wiki to HTML link: link = extract_link(self.env, formatter.context, link) if isinstance(link, Element): link = link.attrib.get('href') else: link = '' location = self._format_address(location) if _reCOORDS.match(location): coord = location.split(':') markers.append( gmarker( coord[0], coord[1], letter, link, title ) ) else: if self.geocoding_server: coord = [] if location == 'center': if address: coord = self._get_coords(address) else: coord = center.split(',') else: coord = self._get_coords(location) markers.append( gmarker( coord[0], coord[1], letter, link, title ) ) else: if location == 'center': if address: markers.append( gmarkeraddr( address, letter, link, title ) ) else: coord = center.split(',') markers.append( gmarker( coord[0], coord[1], letter, link, title ) ) else: markers.append( gmarkeraddr( location, letter, link, title) ) markers_str = ''.join( markers ) # Get macro count from request object req = formatter.req count = getattr (req, COUNT, 0) id = 'tracgooglemap-%s' % count setattr (req, COUNT, count + 1) # Canvas for this map mapdiv = tag.div ( "Google Map is loading ... (JavaScript enabled?)", id=id, style = "width: %s; height: %s;" % (width,height), class_ = "tracgooglemap" ) if 'from' in kwargs and 'to' in kwargs: directions = "from: %s to: %s" % (kwargs['from'],' to: '.join(list(kwargs['to']))) mapnmore = tag.table( tag.tr( tag.td( tag.div( "", class_ = 'tracgooglemap-directions', id = 'tracgooglemap-directions-%s' % count ), style="vertical-align:top;", ), tag.td( mapdiv, style="vertical-align:top;", ) ), class_ = 'tracgooglemaps' ) else: directions = "" mapnmore = mapdiv # put everything in a tidy div html = tag.div( [ # Initialization script for this map tag.script ( Markup( _javascript_code % { 'id':id, 'center':center, 'zoom':zoom, 'address':address, 'type':type, 'width':width, 'height':height, 'types_str':types_str, 'controls_str':controls_str, 'markers_str':markers_str, 'directions':directions, } ), type = "text/javascript"), mapnmore ], class_ = "tracgooglemap-parent" ); return html;
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
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))
def get_absolute_url(url, formatter=None, base=None): """ Generate an absolute url from the url with the special schemes {htdocs,chrome,ticket,wiki,source} simply return the url if given with {http,https,ftp} schemes. Also supports TracLinks. Examples: http://example.com/filename.ext ie. http://www.google.com/logo.jpg htdocs://site/filename.ext htdocs://plugin/dir/filename.ext note: `chrome` is an alias for `htdocs` ticket://number/attachment.pdf ie. ticket://123/specification.pdf wiki://WikiWord/attachment.jpg source://changeset/path/filename.ext ie. source://1024/trunk/docs/README """ def ujoin(*parts): """ Remove double slashes. """ parts = [part.strip('/') for part in parts] return '/' + '/'.join(parts) # You must supply a formatter or a base. if not base: base = formatter.href.base if url.find('://') > 0: scheme, netloc, path, query, params, fragment = urlparse.urlparse(url) if scheme in ('ftp', 'http', 'https'): return url if scheme in ('htdocs', 'chrome'): return ujoin(base, 'chrome', path) if scheme in ('source',): return ujoin(base, 'export', path) if scheme in ('ticket',): return ujoin(base, 'raw-attachment/ticket', path) if scheme in ('wiki',): return ujoin(base, 'raw-attachment/wiki', path) return url # You'll need a formatter for this, code from #3938, serious testing needed. else: link = extract_link(formatter.env, formatter.context, url) if isinstance(link, Element): url = link.attrib.get('href') scheme, netloc, path, query, params, fragment = urlparse.urlparse(url) if path.startswith('/browser/'): query_dict = xform_query(query) query_dict['format'] = 'raw' query = xfrom_query(query_dict) url = urlparse.urlunparse((scheme, netloc, path, query, params, fragment)) elif path.startswith('/attachement/'): url = url.replace('/attachment/', '/raw-attachment/', 1) return url