~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugins/launchpad/lp_indirect.py

  • Committer: Alexander Belchenko
  • Date: 2008-01-28 22:48:19 UTC
  • mto: This revision was merged to the branch mainline in revision 3230.
  • Revision ID: bialix@ukr.net-20080128224819-88buaniv5dwy9vx4
$BZR_LOG is used to contol location of .bzr.log (use /dev/null or NUL to suppress log).

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
again.
23
23
"""
24
24
 
 
25
from urlparse import urlsplit, urlunsplit
 
26
import xmlrpclib
 
27
 
25
28
from bzrlib import (
 
29
    debug,
26
30
    errors,
 
31
    trace,
 
32
    urlutils,
27
33
    )
28
34
from bzrlib.transport import (
29
35
    get_transport,
 
36
    register_urlparse_netloc_protocol,
30
37
    Transport,
31
38
    )
32
39
 
33
 
 
34
 
def launchpad_transport_indirect(base_url):
35
 
    """Uses Launchpad.net as a directory of open source software"""
36
 
    if base_url.startswith('lp:///'):
37
 
        real_url = 'http://code.launchpad.net/' + base_url[6:]
38
 
    elif base_url.startswith('lp:') and base_url[3] != '/':
39
 
        real_url = 'http://code.launchpad.net/' + base_url[3:]
40
 
    else:
41
 
        raise errors.InvalidURL(path=base_url)
42
 
    return get_transport(real_url)
 
40
from bzrlib.plugins.launchpad.lp_registration import (
 
41
    LaunchpadService, ResolveLaunchpadPathRequest)
 
42
from bzrlib.plugins.launchpad.account import get_lp_login
 
43
 
 
44
 
 
45
# As bzrlib.transport.remote may not be loaded yet, make sure bzr+ssh
 
46
# is counted as a netloc protocol.
 
47
register_urlparse_netloc_protocol('bzr+ssh')
 
48
register_urlparse_netloc_protocol('lp')
 
49
 
 
50
 
 
51
class LaunchpadTransport(Transport):
 
52
    """lp:/// URL transport
 
53
 
 
54
    This transport redirects requests to the real branch location
 
55
    after resolving the URL via an XMLRPC request to Launchpad.
 
56
    """
 
57
 
 
58
    def __init__(self, base):
 
59
        super(LaunchpadTransport, self).__init__(base)
 
60
        # We only support URLs without a netloc
 
61
        netloc = urlsplit(base)[1]
 
62
        if netloc != '':
 
63
            raise errors.InvalidURL(path=base)
 
64
 
 
65
    def _requires_launchpad_login(self, scheme, netloc, path, query,
 
66
                                  fragment):
 
67
        """Does the URL require a Launchpad login in order to be reached?
 
68
 
 
69
        The URL is specified by its parsed components, as returned from
 
70
        urlsplit.
 
71
        """
 
72
        return (scheme in ('bzr+ssh', 'sftp')
 
73
                and (netloc.endswith('launchpad.net')
 
74
                     or netloc.endswith('launchpad.dev')))
 
75
 
 
76
    def _resolve(self, abspath,
 
77
                 _request_factory=ResolveLaunchpadPathRequest,
 
78
                 _lp_login=None):
 
79
        """Resolve the base URL for this transport."""
 
80
        path = urlsplit(abspath)[2].lstrip('/')
 
81
        # Perform an XMLRPC request to resolve the path
 
82
        resolve = _request_factory(path)
 
83
        service = LaunchpadService()
 
84
        try:
 
85
            result = resolve.submit(service)
 
86
        except xmlrpclib.Fault, fault:
 
87
            raise errors.InvalidURL(
 
88
                path=abspath, extra=fault.faultString)
 
89
 
 
90
        if 'launchpad' in debug.debug_flags:
 
91
            trace.mutter("resolve_lp_path(%r) == %r", path, result)
 
92
 
 
93
        if _lp_login is None:
 
94
            _lp_login = get_lp_login()
 
95
        for url in result['urls']:
 
96
            scheme, netloc, path, query, fragment = urlsplit(url)
 
97
            if self._requires_launchpad_login(scheme, netloc, path, query,
 
98
                                              fragment):
 
99
                # Only accept launchpad.net bzr+ssh URLs if we know
 
100
                # the user's Launchpad login:
 
101
                if _lp_login is None:
 
102
                    continue
 
103
                url = urlunsplit((scheme, '%s@%s' % (_lp_login, netloc),
 
104
                                  path, query, fragment))
 
105
                break
 
106
            else:
 
107
                # Use the URL if we can create a transport for it.
 
108
                try:
 
109
                    get_transport(url)
 
110
                except (errors.PathError, errors.TransportError):
 
111
                    pass
 
112
                else:
 
113
                    break
 
114
        else:
 
115
            raise errors.InvalidURL(path=abspath,
 
116
                                    extra='no supported schemes')
 
117
        return url
 
118
 
 
119
    def _request_redirect(self, relpath):
 
120
        source = urlutils.join(self.base, relpath)
 
121
        # Split the source location into the branch location, and the
 
122
        # extra path components.
 
123
        pos = source.find('/.bzr/')
 
124
        if pos >= 0:
 
125
            branchpath = source[:pos]
 
126
            extra = source[pos:]
 
127
        else:
 
128
            branchpath = source
 
129
            extra = ''
 
130
        target = self._resolve(branchpath) + extra
 
131
        raise errors.RedirectRequested(
 
132
            source=source,
 
133
            target=target)
 
134
 
 
135
    def get(self, relpath):
 
136
        """See Transport.get()."""
 
137
        self._request_redirect(relpath)
 
138
 
 
139
    def mkdir(self, relpath, mode=None):
 
140
        """See Transport.mkdir()."""
 
141
        self._request_redirect(relpath)
43
142
 
44
143
 
45
144
def get_test_permutations():