~launchpad-pqm/launchpad/devel

8687.15.17 by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/.
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
3
5223.3.2 by jml at canonical
Fix up lint.
4
# Disable pylint 'should have "self" as first argument' warnings.
5
# pylint: disable-msg=E0213
6
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
7
"""Branch XMLRPC API."""
8
9
__metaclass__ = type
4984.2.8 by jml at canonical
Add a doctest, hook up the new XML-RPC methods with the xml-rpc server.
10
__all__ = [
11474.5.1 by Tim Penhey
Reformat the __all__ block.
11
    'BranchSetAPI',
12
    'IBranchSetAPI',
13
    'IPublicCodehostingAPI',
14
    'PublicCodehostingAPI',
15
    ]
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
16
9738.1.6 by Michael Hudson
consistently escape message names in error responses
17
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
18
from xmlrpclib import Fault
19
9738.1.6 by Michael Hudson
consistently escape message names in error responses
20
from bzrlib import urlutils
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
21
from zope.component import getUtility
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
22
from zope.interface import (
23
    implements,
24
    Interface,
25
    )
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
26
4984.2.1 by jml at canonical
Start of implementation of public XML-RPC API for expanding lp:/// URLs.
27
from canonical.config import config
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
28
from canonical.launchpad.webapp import (
29
    canonical_url,
30
    LaunchpadXMLRPCView,
31
    )
32
from canonical.launchpad.webapp.interfaces import ILaunchBag
33
from canonical.launchpad.xmlrpc import faults
34
from canonical.launchpad.xmlrpc.helpers import return_fault
11270.1.3 by Tim Penhey
Changed NotFoundError imports - gee there were a lot of them.
35
from lp.app.errors import NotFoundError
12442.2.9 by j.c.sackett
Ran import reformatter per review.
36
from lp.app.validators import LaunchpadValidationError
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
37
from lp.bugs.interfaces.bug import IBugSet
8555.2.2 by Tim Penhey
Move enum -> enums.
38
from lp.code.enums import BranchType
11270.2.3 by Tim Penhey
Fix more imports.
39
from lp.code.errors import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
40
    BranchCreationException,
41
    BranchCreationForbidden,
42
    CannotHaveLinkedBranch,
43
    InvalidNamespace,
44
    NoLinkedBranch,
45
    NoSuchBranch,
46
    )
11270.2.3 by Tim Penhey
Fix more imports.
47
from lp.code.interfaces.branch import IBranch
8275.3.14 by Jonathan Lange
Clean up some imports.
48
from lp.code.interfaces.branchlookup import IBranchLookup
11270.2.11 by Tim Penhey
Move InvalidNamespace from lp.code.interfaces.branchnamespace to lp.code.errors
49
from lp.code.interfaces.branchnamespace import get_branch_namespace
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
50
from lp.code.interfaces.codehosting import (
51
    BRANCH_ALIAS_PREFIX,
52
    compose_public_url,
53
    SUPPORTED_SCHEMES,
54
    )
11637.3.9 by j.c.sackett
Fixed NoSuchDistroSeries imports.
55
from lp.registry.errors import (
56
    NoSuchDistroSeries,
57
    NoSuchSourcePackageName,
58
    )
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
59
from lp.registry.interfaces.person import (
60
    IPersonSet,
61
    NoSuchPerson,
62
    )
7675.110.3 by Curtis Hovey
Ran the migration script to move registry code to lp.registry.
63
from lp.registry.interfaces.product import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
64
    InvalidProductName,
65
    IProductSet,
66
    NoSuchProduct,
67
    )
7675.110.3 by Curtis Hovey
Ran the migration script to move registry code to lp.registry.
68
from lp.registry.interfaces.productseries import NoSuchProductSeries
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
69
11637.3.19 by j.c.sackett
Fixed import formatting.
70
3313.4.4 by test at canonical
BranchAPI -> BranchSetAPI
71
class IBranchSetAPI(Interface):
4984.2.27 by jml at canonical
Update docstrings to indicate how long we'll be supporting these methods for.
72
    """An XMLRPC interface for dealing with branches.
73
74
    This XML-RPC interface was introduced to support Bazaar 0.8-2, which is
75
    included in Ubuntu 6.06. This interface cannot be removed until Ubuntu
76
    6.06 is end-of-lifed.
77
    """
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
78
79
    def register_branch(branch_url, branch_name, branch_title,
6661.1.1 by Jonathan Lange
Allow people to specify the team of a branch when registering over XMLRPC.
80
                        branch_description, author_email, product_name,
81
                        owner_name=''):
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
82
        """Register a new branch in Launchpad."""
83
8339.2.9 by Paul Hummer
Fixed broken tests
84
    def link_branch_to_bug(branch_url, bug_id):
3313.4.5 by test at canonical
add IBranchSetAPI.link_branch_to_bug()
85
        """Link the branch to the bug."""
86
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
87
3313.4.4 by test at canonical
BranchAPI -> BranchSetAPI
88
class BranchSetAPI(LaunchpadXMLRPCView):
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
89
3313.4.4 by test at canonical
BranchAPI -> BranchSetAPI
90
    implements(IBranchSetAPI)
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
91
92
    def register_branch(self, branch_url, branch_name, branch_title,
6661.1.1 by Jonathan Lange
Allow people to specify the team of a branch when registering over XMLRPC.
93
                        branch_description, author_email, product_name,
94
                        owner_name=''):
3313.4.4 by test at canonical
BranchAPI -> BranchSetAPI
95
        """See IBranchSetAPI."""
6661.1.1 by Jonathan Lange
Allow people to specify the team of a branch when registering over XMLRPC.
96
        registrant = getUtility(ILaunchBag).user
97
        assert registrant is not None, (
3313.4.17 by Bjorn Tillenius
review comments.
98
            "register_branch shouldn't be accessible to unauthenicated"
99
            " requests.")
6661.1.1 by Jonathan Lange
Allow people to specify the team of a branch when registering over XMLRPC.
100
101
        person_set = getUtility(IPersonSet)
102
        if owner_name:
103
            owner = person_set.getByName(owner_name)
104
            if owner is None:
6715.4.6 by Michael Hudson
more
105
                return faults.NoSuchPersonWithName(owner_name)
6661.1.1 by Jonathan Lange
Allow people to specify the team of a branch when registering over XMLRPC.
106
            if not registrant.inTeam(owner):
6715.4.6 by Michael Hudson
more
107
                return faults.NotInTeam(registrant.name, owner_name)
6661.1.1 by Jonathan Lange
Allow people to specify the team of a branch when registering over XMLRPC.
108
        else:
109
            owner = registrant
110
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
111
        if product_name:
112
            product = getUtility(IProductSet).getByName(product_name)
113
            if product is None:
3313.4.15 by Bjorn Tillenius
define subclasses for each XMLRPC fault code.
114
                return faults.NoSuchProduct(product_name)
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
115
        else:
116
            product = None
117
3691.194.1 by James Henstridge
strip trailing slashes from provided URL, fixing bug #52780
118
        # Branch URLs in Launchpad do not end in a slash, so strip any
119
        # slashes from the end of the URL.
120
        branch_url = branch_url.rstrip('/')
121
7940.2.9 by Jonathan Lange
Fix up a bunch of tests. Make IBranchSet.__getitem__ delegate to IBranchLookup.
122
        branch_lookup = getUtility(IBranchLookup)
123
        existing_branch = branch_lookup.getByUrl(branch_url)
3313.4.12 by Bjorn Tillenius
return an error if the branch already is registered.
124
        if existing_branch is not None:
3313.4.15 by Bjorn Tillenius
define subclasses for each XMLRPC fault code.
125
            return faults.BranchAlreadyRegistered(branch_url)
3313.4.12 by Bjorn Tillenius
return an error if the branch already is registered.
126
4506.2.1 by David Allouche
BranchSetAPI.register_branch returns a fault if the branch_url is not a valid URI.
127
        try:
4506.2.3 by David Allouche
Use IBranch.url validator. Detect unique branch name conflicts.
128
            unicode_branch_url = branch_url.decode('utf-8')
9738.1.6 by Michael Hudson
consistently escape message names in error responses
129
            IBranch['url'].validate(unicode_branch_url)
4506.2.3 by David Allouche
Use IBranch.url validator. Detect unique branch name conflicts.
130
        except LaunchpadValidationError, exc:
131
            return faults.InvalidBranchUrl(branch_url, exc)
4506.2.1 by David Allouche
BranchSetAPI.register_branch returns a fault if the branch_url is not a valid URI.
132
3313.4.18 by Bjorn Tillenius
branch title isn't required anymore, so set it to None if it isn't specified.
133
        # We want it to be None in the database, not ''.
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
134
        if not branch_description:
135
            branch_description = None
3313.4.18 by Bjorn Tillenius
branch title isn't required anymore, so set it to None if it isn't specified.
136
        if not branch_title:
137
            branch_title = None
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
138
139
        if not branch_name:
6661.1.4 by Jonathan Lange
Fix bug 209892. Raise a sane error when a branch name is invalid.
140
            branch_name = unicode_branch_url.split('/')[-1]
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
141
4333.5.5 by Tim Penhey
Updating the views for creating branches, and the XMLRPC views
142
        try:
4359.2.6 by Tim Penhey
Fix branch creation over xmlrpc again.
143
            if branch_url:
144
                branch_type = BranchType.MIRRORED
145
            else:
146
                branch_type = BranchType.HOSTED
7959.1.16 by Tim Penhey
Fix the doctests.
147
            namespace = get_branch_namespace(owner, product)
148
            branch = namespace.createBranch(
4359.2.6 by Tim Penhey
Fix branch creation over xmlrpc again.
149
                branch_type=branch_type,
7959.1.16 by Tim Penhey
Fix the doctests.
150
                name=branch_name, registrant=registrant,
151
                url=branch_url, title=branch_title,
7362.15.1 by Tim Penhey
Fix remaining tests.
152
                summary=branch_description)
4652.1.14 by Jonathan Lange
Request a mirror when a branch is registered over XML-RPC
153
            if branch_type == BranchType.MIRRORED:
154
                branch.requestMirror()
4333.5.5 by Tim Penhey
Updating the views for creating branches, and the XMLRPC views
155
        except BranchCreationForbidden:
156
            return faults.BranchCreationForbidden(product.displayname)
6194.1.1 by Tim Penhey
Back out the change that required branches names to be unique across a product, but keep the good error messages.
157
        except BranchCreationException, err:
158
            return faults.BranchNameInUse(err)
6661.1.5 by Jonathan Lange
Check unicode. Some refactoring.
159
        except LaunchpadValidationError, err:
160
            return faults.InvalidBranchName(err)
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
161
3313.4.2 by Bjorn Tillenius
make the branch author optional, defaulting to the the owner. return the canonical url of the branch in Launchpad after registering it.
162
        return canonical_url(branch)
3313.4.1 by Bjorn Tillenius
add an XMLRPC method for registering branches.
163
8339.2.9 by Paul Hummer
Fixed broken tests
164
    def link_branch_to_bug(self, branch_url, bug_id):
3313.4.5 by test at canonical
add IBranchSetAPI.link_branch_to_bug()
165
        """See IBranchSetAPI."""
7940.2.5 by Jonathan Lange
Move branch lookup methods to IBranchLookup
166
        branch = getUtility(IBranchLookup).getByUrl(url=branch_url)
3313.4.5 by test at canonical
add IBranchSetAPI.link_branch_to_bug()
167
        if branch is None:
3313.4.15 by Bjorn Tillenius
define subclasses for each XMLRPC fault code.
168
            return faults.NoSuchBranch(branch_url)
3313.4.5 by test at canonical
add IBranchSetAPI.link_branch_to_bug()
169
        try:
170
            bug = getUtility(IBugSet).get(bug_id)
171
        except NotFoundError:
3313.4.15 by Bjorn Tillenius
define subclasses for each XMLRPC fault code.
172
            return faults.NoSuchBug(bug_id)
5001.1.9 by Tim Penhey
Updates following review.
173
        # Since this API is controlled using launchpad.AnyPerson there must be
174
        # an authenticated person, so use this person as the registrant.
175
        registrant = getUtility(ILaunchBag).user
8698.10.4 by Paul Hummer
Fixed references to broken code
176
        bug.linkBranch(branch, registrant=registrant)
3313.4.5 by test at canonical
add IBranchSetAPI.link_branch_to_bug()
177
        return canonical_url(bug)
178
179
4984.2.1 by jml at canonical
Start of implementation of public XML-RPC API for expanding lp:/// URLs.
180
class IPublicCodehostingAPI(Interface):
181
    """The public codehosting API."""
182
4984.2.8 by jml at canonical
Add a doctest, hook up the new XML-RPC methods with the xml-rpc server.
183
    def resolve_lp_path(path):
4984.2.17 by jml at canonical
Add docstrings and improve test comments.
184
        """Expand the path segment of an lp: URL into a list of branch URLs.
185
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
186
        This method is added to Bazaar in 0.93.
4984.2.27 by jml at canonical
Update docstrings to indicate how long we'll be supporting these methods for.
187
4984.2.17 by jml at canonical
Add docstrings and improve test comments.
188
        :return: A dict containing a single 'urls' key that maps to a list of
189
            URLs. Clients should use the first URL in the list that they can
6715.4.2 by Michael Hudson
docstrings
190
            support.  Returns a Fault if the path does not resolve to a
191
            branch.
4984.2.1 by jml at canonical
Start of implementation of public XML-RPC API for expanding lp:/// URLs.
192
        """
193
4984.2.13 by jml at canonical
Return the requested branch path if a branch doesn't exist.
194
195
class _NonexistentBranch:
196
    """Used to represent a branch that was requested but doesn't exist."""
197
198
    def __init__(self, unique_name):
199
        self.unique_name = unique_name
200
        self.branch_type = None
201
202
4984.2.1 by jml at canonical
Start of implementation of public XML-RPC API for expanding lp:/// URLs.
203
class PublicCodehostingAPI(LaunchpadXMLRPCView):
204
    """See `IPublicCodehostingAPI`."""
205
4984.2.8 by jml at canonical
Add a doctest, hook up the new XML-RPC methods with the xml-rpc server.
206
    implements(IPublicCodehostingAPI)
207
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
208
    def _compose_http_url(unique_name, path, suffix):
209
        return compose_public_url('http', unique_name, suffix)
210
211
    def _compose_bzr_ssh_url(unique_name, path, suffix):
212
        if not path.startswith('~'):
213
            path = '%s/%s' % (BRANCH_ALIAS_PREFIX, path)
214
        return compose_public_url('bzr+ssh', path, suffix)
215
216
    scheme_funcs = {
217
        'bzr+ssh': _compose_bzr_ssh_url,
218
        'http': _compose_http_url,
219
        }
220
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
221
    def _getUrlsForBranch(self, branch, lp_path, suffix=None,
222
                          supported_schemes=None):
223
        """Return a list of URLs for the given branch.
4984.2.17 by jml at canonical
Add docstrings and improve test comments.
224
7238.3.5 by Aaron Bentley
Cleanup
225
        :param branch: A Branch object.
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
226
        :param lp_path: The path that was used to traverse to the branch.
4984.2.17 by jml at canonical
Add docstrings and improve test comments.
227
        :param suffix: The section of the path that follows the branch
228
            specification.
229
        :return: {'urls': [list_of_branch_urls]}.
230
        """
4984.2.10 by jml at canonical
Add support for remote branches.
231
        if branch.branch_type == BranchType.REMOTE:
6903.1.6 by Michael Hudson
implementation for remote-branch-without-a-URL bug
232
            if branch.url is None:
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
233
                raise faults.NoUrlForBranch(branch.unique_name)
234
            return [branch.url]
4984.2.10 by jml at canonical
Add support for remote branches.
235
        else:
8855.1.2 by Michael Hudson
tweaks and a passing test
236
            return self._getUniqueNameResultDict(
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
237
                branch.unique_name, suffix, supported_schemes, lp_path)
7238.3.5 by Aaron Bentley
Cleanup
238
8855.1.2 by Michael Hudson
tweaks and a passing test
239
    def _getUniqueNameResultDict(self, unique_name, suffix=None,
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
240
                                 supported_schemes=None, path=None):
8855.1.2 by Michael Hudson
tweaks and a passing test
241
        if supported_schemes is None:
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
242
            supported_schemes = SUPPORTED_SCHEMES
243
        if path is None:
244
            path = unique_name
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
245
        return [self.scheme_funcs[scheme](unique_name, path, suffix)
246
                for scheme in supported_schemes]
4984.2.10 by jml at canonical
Add support for remote branches.
247
7940.3.1 by Jonathan Lange
Move return_fault to a helpers module, and make resolve_lp_path use it,
248
    @return_fault
249
    def _resolve_lp_path(self, path):
6715.4.5 by Michael Hudson
stop trying to be fancy
250
        """See `IPublicCodehostingAPI`."""
7940.3.1 by Jonathan Lange
Move return_fault to a helpers module, and make resolve_lp_path use it,
251
        # Separate method because Zope's mapply raises errors if we use
7940.3.45 by Jonathan Lange
Clarify comment
252
        # decorators in XMLRPC methods. mapply checks that the passed
253
        # arguments match the formal parameters. Decorators normally have
254
        # *args and **kwargs, which mapply fails on.
4984.2.7 by jml at canonical
Test some edge cases, add docstrings, add checks for private branches.
255
        strip_path = path.strip('/')
256
        if strip_path == '':
7940.3.1 by Jonathan Lange
Move return_fault to a helpers module, and make resolve_lp_path use it,
257
            raise faults.InvalidBranchIdentifier(path)
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
258
        supported_schemes = list(SUPPORTED_SCHEMES)
8855.1.2 by Michael Hudson
tweaks and a passing test
259
        hot_products = [product.strip() for product
260
                        in config.codehosting.hot_products.split(',')]
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
261
        # If we have been given something that looks like a branch name, just
262
        # look that up.
263
        if strip_path.startswith('~'):
264
            urls = self._getBranchPaths(strip_path, supported_schemes)
265
        else:
266
            # We only check the hot product code when accessed through the
267
            # short name, so we can check it here.
268
            if strip_path in hot_products:
269
                supported_schemes = ['http']
270
                urls = []
271
            else:
272
                urls = [self.scheme_funcs['bzr+ssh'](None, strip_path, None)]
273
                supported_schemes.remove('bzr+ssh')
274
            # Try to look up the branch at that url and add alternative URLs.
275
            # This may well fail, and if it does, we just return the aliased
276
            # url.
277
            try:
278
                urls.extend(
279
                    self._getBranchPaths(strip_path, supported_schemes))
280
            except Fault:
281
                pass
282
        return dict(urls=urls)
283
284
    def _getBranchPaths(self, strip_path, supported_schemes):
285
        """Get the specific paths for a branch.
286
287
        If the branch is not found, but it looks like a branch name, then we
288
        return a writable URL for it.  If it doesn't look like a branch name a
289
        fault is raised.
290
        """
7940.2.5 by Jonathan Lange
Move branch lookup methods to IBranchLookup
291
        branch_set = getUtility(IBranchLookup)
7238.3.2 by Aaron Bentley
Get getByLPPath passing some tests
292
        try:
7940.3.27 by Jonathan Lange
No need to return series! yay!
293
            branch, suffix = branch_set.getByLPPath(strip_path)
7362.10.6 by Jonathan Lange
Raise a real NoSuchBranch error, not a fault.
294
        except NoSuchBranch:
7940.3.19 by Jonathan Lange
Lots of comments, docstring tweaks and todos.
295
            # If the branch isn't found, but it looks like a valid name, then
296
            # resolve it anyway, treating the path like a branch's unique
297
            # name. This lets people push new branches up to Launchpad using
298
            # lp: URL syntax.
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
299
            supported_schemes = ['bzr+ssh']
300
            return self._getUniqueNameResultDict(
301
                strip_path, supported_schemes=supported_schemes)
7940.3.44 by Jonathan Lange
Add a bug number
302
        # XXX: JonathanLange 2009-03-21 bug=347728: All of this is repetitive
303
        # and thus error prone. Alternatives are directly raising faults from
304
        # the model code(blech) or some automated way of reraising as faults
305
        # or using a narrower range of faults (e.g. only one "NoSuch" fault).
7940.3.9 by Jonathan Lange
Get rid of the last of the faults used in branchlookup.
306
        except InvalidProductName, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
307
            raise faults.InvalidProductIdentifier(urlutils.escape(e.name))
7940.3.7 by Jonathan Lange
Don't raise the series fault from the model method.
308
        except NoSuchProductSeries, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
309
            raise faults.NoSuchProductSeries(
310
                urlutils.escape(e.name), e.product)
7362.10.10 by Jonathan Lange
Raise NoSuchPerson, rather than a crappy fault.
311
        except NoSuchPerson, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
312
            raise faults.NoSuchPersonWithName(urlutils.escape(e.name))
7940.3.14 by Jonathan Lange
Change getByLPPath to use pillars rather than products for the first
313
        except NoSuchProduct, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
314
            raise faults.NoSuchProduct(urlutils.escape(e.name))
7940.3.36 by Jonathan Lange
Handle no such distro series.
315
        except NoSuchDistroSeries, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
316
            raise faults.NoSuchDistroSeries(urlutils.escape(e.name))
7940.3.37 by Jonathan Lange
Handle no such source package name.
317
        except NoSuchSourcePackageName, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
318
            raise faults.NoSuchSourcePackageName(urlutils.escape(e.name))
7940.3.26 by Jonathan Lange
Reconcile the exception handling, which may well make the code clearer.
319
        except NoLinkedBranch, e:
320
            raise faults.NoLinkedBranch(e.component)
321
        except CannotHaveLinkedBranch, e:
322
            raise faults.CannotHaveLinkedBranch(e.component)
7940.3.33 by Jonathan Lange
Raise a nice error if the branch name is too short.
323
        except InvalidNamespace, e:
9738.1.6 by Michael Hudson
consistently escape message names in error responses
324
            raise faults.InvalidBranchUniqueName(urlutils.escape(e.name))
11474.5.4 by Tim Penhey
Move the compose_public_url method and tweak the url repsonses to expand non-user urls to use +branch.
325
        # Reverse engineer the actual lp_path that is used, so we need to
326
        # remove any suffix that may be there from the strip_path.
327
        lp_path = strip_path
328
        if suffix is not None:
329
            # E.g. 'project/trunk/filename.txt' the suffix is 'filename.txt'
330
            # we want lp_path to be 'project/trunk'.
331
            lp_path = lp_path[:-(len(suffix)+1)]
11474.5.13 by Tim Penhey
Update the tests to the expected behaviour when resolving names that don't directly represent a branch unique name. Now the resolver doesn't care as much, and passes the concern over to the codehosting path resolver.
332
        return self._getUrlsForBranch(
333
            branch, lp_path, suffix, supported_schemes)
7940.3.1 by Jonathan Lange
Move return_fault to a helpers module, and make resolve_lp_path use it,
334
335
    def resolve_lp_path(self, path):
336
        """See `IPublicCodehostingAPI`."""
337
        return self._resolve_lp_path(path)