~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
 
1
# Copyright (C) 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
"""Transport indirection that uses Launchpad as a directory lookup.
19
 
 
20
 
When the transport is opened, it immediately redirects to a url
21
 
on Launchpad, which can then either serve the branch itself or redirect
22
 
again.
23
 
"""
 
18
"""Directory lookup that uses Launchpad."""
24
19
 
25
20
from urlparse import urlsplit, urlunsplit
26
21
import xmlrpclib
34
29
from bzrlib.transport import (
35
30
    get_transport,
36
31
    register_urlparse_netloc_protocol,
37
 
    Transport,
38
32
    )
39
33
 
40
34
from bzrlib.plugins.launchpad.lp_registration import (
48
42
register_urlparse_netloc_protocol('lp')
49
43
 
50
44
 
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)
 
45
class LaunchpadDirectory(object):
64
46
 
65
47
    def _requires_launchpad_login(self, scheme, netloc, path, query,
66
48
                                  fragment):
73
55
                and (netloc.endswith('launchpad.net')
74
56
                     or netloc.endswith('launchpad.dev')))
75
57
 
76
 
    def _resolve(self, abspath,
 
58
    def look_up(self, name, url):
 
59
        """See DirectoryService.look_up"""
 
60
        return self._resolve(url)
 
61
 
 
62
    def _resolve(self, url,
77
63
                 _request_factory=ResolveLaunchpadPathRequest,
78
64
                 _lp_login=None):
79
65
        """Resolve the base URL for this transport."""
80
 
        path = urlsplit(abspath)[2].lstrip('/')
 
66
        result = urlsplit(url)
81
67
        # Perform an XMLRPC request to resolve the path
82
 
        resolve = _request_factory(path)
83
 
        service = LaunchpadService()
 
68
        lp_instance = result[1]
 
69
        if lp_instance == '':
 
70
            lp_instance = None
 
71
        elif lp_instance not in LaunchpadService.LAUNCHPAD_INSTANCE:
 
72
            raise errors.InvalidURL(path=url)
 
73
        resolve = _request_factory(result[2].strip('/'))
 
74
        service = LaunchpadService(lp_instance=lp_instance)
84
75
        try:
85
76
            result = resolve.submit(service)
86
77
        except xmlrpclib.Fault, fault:
87
78
            raise errors.InvalidURL(
88
 
                path=abspath, extra=fault.faultString)
 
79
                path=url, extra=fault.faultString)
89
80
 
90
81
        if 'launchpad' in debug.debug_flags:
91
82
            trace.mutter("resolve_lp_path(%r) == %r", path, result)
112
103
                else:
113
104
                    break
114
105
        else:
115
 
            raise errors.InvalidURL(path=abspath,
116
 
                                    extra='no supported schemes')
 
106
            raise errors.InvalidURL(path=url, extra='no supported schemes')
117
107
        return url
118
108
 
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)
142
 
 
143
109
 
144
110
def get_test_permutations():
145
111
    # Since this transport doesn't do anything once opened, it's not subjected