~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2009-06-19 17:53:37 UTC
  • mto: This revision was merged to the branch mainline in revision 4466.
  • Revision ID: john@arbash-meinel.com-20090619175337-uozt3bntdd48lh4z
Update time_graph to use X:1 ratios rather than 0.xxx ratios.
It is just easier to track now that the new code is much faster.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
 
18
from getpass import getpass
18
19
import os
19
 
import socket
20
20
from urlparse import urlsplit, urlunsplit
21
21
import urllib
22
22
import xmlrpclib
23
23
 
 
24
from bzrlib.lazy_import import lazy_import
 
25
lazy_import(globals(), """
 
26
from bzrlib import urlutils
 
27
""")
 
28
 
24
29
from bzrlib import (
25
30
    config,
26
31
    errors,
27
 
    urlutils,
28
32
    __version__ as _bzrlib_version,
29
33
    )
30
 
from bzrlib.transport.http import _urllib2_wrappers
31
 
 
32
34
 
33
35
# for testing, do
34
36
'''
51
53
        errors.BzrError.__init__(self, url=url)
52
54
 
53
55
 
54
 
class XMLRPCTransport(xmlrpclib.Transport):
55
 
 
56
 
    def __init__(self, scheme):
57
 
        # In python2.4 xmlrpclib.Transport is a old-style class, and does not
58
 
        # define __init__, so we check first
59
 
        init = getattr(xmlrpclib.Transport, '__init__', None)
60
 
        if init is not None:
61
 
            init(self)
62
 
        self._scheme = scheme
63
 
        self._opener = _urllib2_wrappers.Opener()
64
 
        self.verbose = 0
65
 
 
66
 
    def request(self, host, handler, request_body, verbose=0):
67
 
        self.verbose = verbose
68
 
        url = self._scheme + "://" + host + handler
69
 
        request = _urllib2_wrappers.Request("POST", url, request_body)
70
 
        # FIXME: _urllib2_wrappers will override user-agent with its own
71
 
        # request.add_header("User-Agent", self.user_agent)
72
 
        request.add_header("Content-Type", "text/xml")
73
 
 
74
 
        response = self._opener.open(request)
75
 
        if response.code != 200:
76
 
            raise xmlrpclib.ProtocolError(host + handler, response.code,
77
 
                                          response.msg, response.info())
78
 
        return self.parse_response(response)
79
 
 
80
 
 
81
56
class LaunchpadService(object):
82
57
    """A service to talk to Launchpad via XMLRPC.
83
58
 
84
 
    See http://wiki.bazaar.canonical.com/Specs/LaunchpadRpc for the methods we can call.
 
59
    See http://bazaar-vcs.org/Specs/LaunchpadRpc for the methods we can call.
85
60
    """
86
61
 
87
62
    LAUNCHPAD_DOMAINS = {
98
73
    for instance, domain in LAUNCHPAD_DOMAINS.iteritems():
99
74
        LAUNCHPAD_INSTANCE[instance] = 'https://xmlrpc.%s/bazaar/' % domain
100
75
 
101
 
    # Previously 'edge' was used to avoid a launchpad bug with redirection
102
 
    DEFAULT_INSTANCE = 'production'
 
76
    # We use edge as the default because:
 
77
    # Beta users get redirected to it
 
78
    # All users can use it
 
79
    # There is a bug in the launchpad side where redirection causes an OOPS.
 
80
    DEFAULT_INSTANCE = 'edge'
103
81
    DEFAULT_SERVICE_URL = LAUNCHPAD_INSTANCE[DEFAULT_INSTANCE]
104
82
 
105
83
    transport = None
112
90
        self._lp_instance = lp_instance
113
91
        if transport is None:
114
92
            uri_type = urllib.splittype(self.service_url)[0]
115
 
            transport = XMLRPCTransport(uri_type)
 
93
            if uri_type == 'https':
 
94
                transport = xmlrpclib.SafeTransport()
 
95
            else:
 
96
                transport = xmlrpclib.Transport()
116
97
            transport.user_agent = 'bzr/%s (xmlrpclib/%s)' \
117
98
                    % (_bzrlib_version, xmlrpclib.__version__)
118
99
        self.transport = transport
119
100
 
 
101
 
120
102
    @property
121
103
    def service_url(self):
122
104
        """Return the http or https url for the xmlrpc server.
134
116
        else:
135
117
            return self.DEFAULT_SERVICE_URL
136
118
 
137
 
    @classmethod
138
 
    def for_url(cls, url, **kwargs):
139
 
        """Return the Launchpad service corresponding to the given URL."""
140
 
        result = urlsplit(url)
141
 
        lp_instance = result[1]
142
 
        if lp_instance == '':
143
 
            lp_instance = None
144
 
        elif lp_instance not in cls.LAUNCHPAD_INSTANCE:
145
 
            raise errors.InvalidURL(path=url)
146
 
        return cls(lp_instance=lp_instance, **kwargs)
147
 
 
148
119
    def get_proxy(self, authenticated):
149
120
        """Return the proxy for XMLRPC requests."""
150
121
        if authenticated:
206
177
                # TODO: print more headers to help in tracking down failures
207
178
                raise errors.BzrError("xmlrpc protocol error connecting to %s: %s %s"
208
179
                        % (self.service_url, e.errcode, e.errmsg))
209
 
        except socket.gaierror, e:
210
 
            raise errors.ConnectionError(
211
 
                "Could not resolve '%s'" % self.domain,
212
 
                orig_error=e)
213
180
        return result
214
181
 
215
182
    @property
220
187
            instance = self._lp_instance
221
188
        return self.LAUNCHPAD_DOMAINS[instance]
222
189
 
223
 
    def _guess_branch_path(self, branch_url, _request_factory=None):
 
190
    def get_web_url_from_branch_url(self, branch_url, _request_factory=None):
 
191
        """Get the Launchpad web URL for the given branch URL.
 
192
 
 
193
        :raise errors.InvalidURL: if 'branch_url' cannot be identified as a
 
194
            Launchpad branch URL.
 
195
        :return: The URL of the branch on Launchpad.
 
196
        """
224
197
        scheme, hostinfo, path = urlsplit(branch_url)[:3]
225
198
        if _request_factory is None:
226
199
            _request_factory = ResolveLaunchpadPathRequest
238
211
                for domain in self.LAUNCHPAD_DOMAINS.itervalues())
239
212
            if hostinfo not in domains:
240
213
                raise NotLaunchpadBranch(branch_url)
241
 
        return path.lstrip('/')
242
 
 
243
 
    def get_web_url_from_branch_url(self, branch_url, _request_factory=None):
244
 
        """Get the Launchpad web URL for the given branch URL.
245
 
 
246
 
        :raise errors.InvalidURL: if 'branch_url' cannot be identified as a
247
 
            Launchpad branch URL.
248
 
        :return: The URL of the branch on Launchpad.
249
 
        """
250
 
        path = self._guess_branch_path(branch_url, _request_factory)
251
214
        return urlutils.join('https://code.%s' % self.domain, path)
252
215
 
253
216
 
351
314
    def __init__(self, path):
352
315
        if not path:
353
316
            raise errors.InvalidURL(path=path,
354
 
                                    extra="You must specify a project.")
 
317
                                    extra="You must specify a product.")
355
318
        self.path = path
356
319
 
357
320
    def _request_params(self):