File: //usr/lib/python3/dist-packages/trac/wiki/intertrac.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2005-2021 Edgewall Software
# Copyright (C) 2005-2006 Christian Boos <cboos@edgewall.org>
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://trac.edgewall.org/wiki/TracLicense.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at https://trac.edgewall.org/log/.
#
# Author: Christian Boos <cboos@edgewall.org>
import re
from trac.config import ConfigSection
from trac.core import *
from trac.util.html import Element, Fragment, find_element, tag
from trac.util.translation import N_, _, tag_
from trac.web.api import IRequestHandler
from trac.wiki.api import IWikiMacroProvider
from trac.wiki.formatter import extract_link
class InterTracDispatcher(Component):
"""InterTrac dispatcher."""
implements(IRequestHandler, IWikiMacroProvider)
is_valid_default_handler = False
intertrac_section = ConfigSection('intertrac',
"""This section configures InterTrac prefixes. Option names in
this section that contain a `.` are of the format
`<name>.<attribute>`. Option names that don't contain a `.` define
an alias.
The `.url` attribute is mandatory and is used for locating the
other Trac. This can be a relative path when the other Trac
environment is located on the same server.
The `.title` attribute is used for generating a tooltip when the
cursor is hovered over an InterTrac link.
Example configuration:
{{{#!ini
[intertrac]
# -- Example of setting up an alias:
t = trac
# -- Link to an external Trac:
genshi.title = Edgewall's Trac for Genshi
genshi.url = https://genshi.edgewall.org
}}}
""")
# IRequestHandler methods
def match_request(self, req):
match = re.match(r'^/intertrac/(.*)', req.path_info)
if match:
if match.group(1):
req.args['link'] = match.group(1)
return True
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:
raise TracError(
_("Can't view %(link)s. Resource doesn't exist or "
"you don't have the required permission.", link=link))
href = elt.attrib.get('href').unescape()
else:
href = req.href(link.rstrip(':'))
req.redirect(href)
# IWikiMacroProvider methods
def get_macros(self):
yield 'InterTrac'
def get_macro_description(self, name):
return 'messages', N_("Provide a list of known InterTrac prefixes.")
def expand_macro(self, formatter, name, content):
intertracs = {}
for key, value in self.intertrac_section.options():
idx = key.rfind('.')
if idx > 0: # 0 itself doesn't help much: .xxx = ...
prefix, attribute = key[:idx], key[idx+1:]
intertrac = intertracs.setdefault(prefix, {})
try:
intertrac[attribute] = value
except TypeError: # alias
pass
else:
intertracs[key] = value # alias
intertracs.setdefault('trac', {'title': _('The Trac Project'),
'url': 'https://trac.edgewall.org'})
def generate_prefix(prefix):
intertrac = intertracs[prefix]
if isinstance(intertrac, str):
yield tag.tr(tag.td(tag.strong(prefix)),
tag.td(tag_("Alias for %(name)s",
name=tag.strong(intertrac))))
else:
url = intertrac.get('url')
if url:
title = intertrac.get('title', url)
yield tag.tr(tag.td(tag.a(tag.strong(prefix),
href=url + '/timeline')),
tag.td(tag.a(title, href=url)))
return tag.table(class_="wiki intertrac")(
tag.tr(tag.th(tag.em(_("Prefix"))),
tag.th(tag.em(_("Trac Site")))),
[generate_prefix(p) for p in sorted(intertracs)])