58
67
"""See DirectoryService.look_up"""
59
68
return self._resolve(url)
61
def _resolve(self, url,
62
_request_factory=ResolveLaunchpadPathRequest,
64
"""Resolve the base URL for this transport."""
70
def _resolve_locally(self, path, url, _request_factory):
71
# This is the best I could work out about XMLRPC. If an lp: url
72
# includes ~user, then it is specially validated. Otherwise, it is just
73
# sent to +branch/$path.
74
_, netloc, _, _, _ = urlsplit(url)
76
netloc = LaunchpadService.DEFAULT_INSTANCE
77
base_url = LaunchpadService.LAUNCHPAD_DOMAINS[netloc]
78
base = 'bzr+ssh://bazaar.%s/' % (base_url,)
80
if path.startswith('~'):
81
# A ~user style path, validate it a bit.
82
# If a path looks fishy, fall back to asking XMLRPC to
83
# resolve it for us. That way we still get their nicer error
85
parts = path.split('/')
87
or (parts[1] in ('ubuntu', 'debian') and len(parts) < 5)):
88
# This special case requires 5-parts to be valid.
93
return self._resolve_via_xmlrpc(path, url, _request_factory)
94
return {'urls': [base + path]}
96
def _resolve_via_xmlrpc(self, path, url, _request_factory):
65
97
service = LaunchpadService.for_url(url)
66
result = urlsplit(url)
68
_lp_login = get_lp_login()
69
path = result[2].strip('/')
70
if path.startswith('~/'):
72
raise errors.InvalidURL(path=url,
73
extra='Cannot resolve "~" to your username.'
74
' See "bzr help launchpad-login"')
75
path = '~' + _lp_login + path[1:]
76
98
resolve = _request_factory(path)
78
100
result = resolve.submit(service)
79
101
except xmlrpclib.Fault, fault:
80
102
raise errors.InvalidURL(
81
103
path=url, extra=fault.faultString)
106
def _update_url_scheme(self, url):
107
# Do ubuntu: and debianlp: expansions.
108
scheme, netloc, path, query, fragment = urlsplit(url)
109
if scheme in ('ubuntu', 'debianlp'):
110
if scheme == 'ubuntu':
112
distro_series = _ubuntu_series_shortcuts
113
elif scheme == 'debianlp':
115
# No shortcuts for Debian distroseries.
118
raise AssertionError('scheme should be ubuntu: or debianlp:')
119
# Split the path. It's either going to be 'project' or
120
# 'series/project', but recognize that it may be a series we don't
122
path_parts = path.split('/')
123
if len(path_parts) == 1:
124
# It's just a project name.
125
lp_url_template = 'lp:%(distro)s/%(project)s'
126
project = path_parts[0]
128
elif len(path_parts) == 2:
129
# It's a series and project.
130
lp_url_template = 'lp:%(distro)s/%(series)s/%(project)s'
131
series, project = path_parts
133
# There are either 0 or > 2 path parts, neither of which is
134
# supported for these schemes.
135
raise errors.InvalidURL('Bad path: %s' % url)
136
# Expand any series shortcuts, but keep unknown series.
137
series = distro_series.get(series, series)
138
# Hack the url and let the following do the final resolution.
139
url = lp_url_template % dict(
143
scheme, netloc, path, query, fragment = urlsplit(url)
146
def _expand_user(self, path, url, lp_login):
147
if path.startswith('~/'):
149
raise errors.InvalidURL(path=url,
150
extra='Cannot resolve "~" to your username.'
151
' See "bzr help launchpad-login"')
152
path = '~' + lp_login + path[1:]
155
def _resolve(self, url,
156
_request_factory=ResolveLaunchpadPathRequest,
158
"""Resolve the base URL for this transport."""
159
url, path = self._update_url_scheme(url)
160
if _lp_login is None:
161
_lp_login = get_lp_login()
162
path = path.strip('/')
163
path = self._expand_user(path, url, _lp_login)
164
if _lp_login is not None:
165
result = self._resolve_locally(path, url, _request_factory)
166
if 'launchpad' in debug.debug_flags:
168
result = self._resolve_via_xmlrpc(path, url, _request_factory)
170
'resolution for {0}\n local: {1}\n remote: {2}').format(
171
url, local_res['urls'], result['urls']))
173
result = self._resolve_via_xmlrpc(path, url, _request_factory)
83
175
if 'launchpad' in debug.debug_flags:
84
176
trace.mutter("resolve_lp_path(%r) == %r", url, result)