~bzr-pqm/bzr/bzr.dev

3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
1
# Copyright (C) 2007, 2008 Canonical Ltd
2245.8.3 by Martin Pool
Start adding indirection transport
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
3251.4.3 by Aaron Bentley
More renames and cleanups
18
"""Directory lookup that uses Launchpad."""
2245.8.3 by Martin Pool
Start adding indirection transport
19
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
20
from urlparse import urlsplit, urlunsplit
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
21
import xmlrpclib
22
2245.8.4 by Martin Pool
lp:/// indirection works
23
from bzrlib import (
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
24
    debug,
2245.8.4 by Martin Pool
lp:/// indirection works
25
    errors,
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
26
    trace,
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
27
    urlutils,
2245.8.4 by Martin Pool
lp:/// indirection works
28
    )
29
from bzrlib.transport import (
30
    get_transport,
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
31
    register_urlparse_netloc_protocol,
2245.8.4 by Martin Pool
lp:/// indirection works
32
    )
33
2898.4.7 by James Henstridge
Fix up tests.
34
from bzrlib.plugins.launchpad.lp_registration import (
35
    LaunchpadService, ResolveLaunchpadPathRequest)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
36
from bzrlib.plugins.launchpad.account import get_lp_login
37
38
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
39
# As bzrlib.transport.remote may not be loaded yet, make sure bzr+ssh
40
# is counted as a netloc protocol.
41
register_urlparse_netloc_protocol('bzr+ssh')
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
42
register_urlparse_netloc_protocol('lp')
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
43
44
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
45
class LaunchpadDirectory(object):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
46
3031.2.4 by jml at canonical
Only split the URL once.
47
    def _requires_launchpad_login(self, scheme, netloc, path, query,
48
                                  fragment):
49
        """Does the URL require a Launchpad login in order to be reached?
50
51
        The URL is specified by its parsed components, as returned from
52
        urlsplit.
53
        """
3031.2.3 by jml at canonical
Make the test pass -- don't include sftp URLs if there's no lp login.
54
        return (scheme in ('bzr+ssh', 'sftp')
55
                and (netloc.endswith('launchpad.net')
56
                     or netloc.endswith('launchpad.dev')))
3031.2.1 by jml at canonical
Factor out the method that determines if a URL is a LP url.
57
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
58
    def look_up(self, name, url):
3251.4.5 by Aaron Bentley
Add docstring
59
        """See DirectoryService.look_up"""
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
60
        return self._resolve(url)
61
3251.4.3 by Aaron Bentley
More renames and cleanups
62
    def _resolve(self, url,
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
63
                 _request_factory=ResolveLaunchpadPathRequest,
64
                 _lp_login=None):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
65
        """Resolve the base URL for this transport."""
3251.4.3 by Aaron Bentley
More renames and cleanups
66
        result = urlsplit(url)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
67
        # Perform an XMLRPC request to resolve the path
3251.4.7 by Daniel Watkins
Remove Python 2.5-isms
68
        lp_instance = result[1]
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
69
        if lp_instance == '':
70
            lp_instance = None
71
        elif lp_instance not in LaunchpadService.LAUNCHPAD_INSTANCE:
3251.4.3 by Aaron Bentley
More renames and cleanups
72
            raise errors.InvalidURL(path=url)
3251.4.7 by Daniel Watkins
Remove Python 2.5-isms
73
        resolve = _request_factory(result[2].strip('/'))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
74
        service = LaunchpadService(lp_instance=lp_instance)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
75
        try:
76
            result = resolve.submit(service)
77
        except xmlrpclib.Fault, fault:
78
            raise errors.InvalidURL(
3251.4.3 by Aaron Bentley
More renames and cleanups
79
                path=url, extra=fault.faultString)
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
80
2898.4.14 by James Henstridge
* Use urlsplit() to process URLs.
81
        if 'launchpad' in debug.debug_flags:
82
            trace.mutter("resolve_lp_path(%r) == %r", path, result)
83
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
84
        if _lp_login is None:
85
            _lp_login = get_lp_login()
3270.4.1 by James Westby
Warn the user when resolving lp: URLs if they haven't set their login.
86
        _warned_login = False
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
87
        for url in result['urls']:
88
            scheme, netloc, path, query, fragment = urlsplit(url)
3031.2.4 by jml at canonical
Only split the URL once.
89
            if self._requires_launchpad_login(scheme, netloc, path, query,
90
                                              fragment):
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
91
                # Only accept launchpad.net bzr+ssh URLs if we know
92
                # the user's Launchpad login:
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
93
                if _lp_login is None:
3270.4.1 by James Westby
Warn the user when resolving lp: URLs if they haven't set their login.
94
                    if not _warned_login:
95
                        trace.warning('You have not informed bzr of your '
3373.1.1 by John Arbash Meinel
Trivial warning message update when user has not run lp-login
96
                                'launchpad login. If you are attempting a\n'
97
                                'write operation and it fails, run '
98
                                '"bzr launchpad-login YOUR_ID" and try again.')
3270.4.1 by James Westby
Warn the user when resolving lp: URLs if they haven't set their login.
99
                        _warned_login = True
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
100
                    continue
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
101
                url = urlunsplit((scheme, '%s@%s' % (_lp_login, netloc),
102
                                  path, query, fragment))
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
103
                break
2898.4.15 by James Henstridge
Use get_transport() to decide whether Bazaar supports a given URL.
104
            else:
105
                # Use the URL if we can create a transport for it.
106
                try:
107
                    get_transport(url)
108
                except (errors.PathError, errors.TransportError):
109
                    pass
110
                else:
111
                    break
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
112
        else:
3251.4.3 by Aaron Bentley
More renames and cleanups
113
            raise errors.InvalidURL(path=url, extra='no supported schemes')
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
114
        return url
115
2245.8.3 by Martin Pool
Start adding indirection transport
116
117
def get_test_permutations():
118
    # Since this transport doesn't do anything once opened, it's not subjected
119
    # to the usual transport tests.
120
    return []