~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: 2010-05-11 10:45:26 UTC
  • mto: This revision was merged to the branch mainline in revision 5225.
  • Revision ID: john@arbash-meinel.com-20100511104526-zxnstcxta22hzw2n
Implement a compiled extension for parsing the text key out of a CHKInventory value.

Related to bug #562666. This seems to shave 5-10% out of the time spent doing a complete
branch of bzr.dev/launchpad/etc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Canonical Ltd
 
1
# Copyright (C) 2006-2010 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
19
18
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
 
 
29
24
from bzrlib import (
30
25
    config,
31
26
    errors,
 
27
    urlutils,
32
28
    __version__ as _bzrlib_version,
33
29
    )
 
30
from bzrlib.transport.http import _urllib2_wrappers
 
31
 
34
32
 
35
33
# for testing, do
36
34
'''
53
51
        errors.BzrError.__init__(self, url=url)
54
52
 
55
53
 
 
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
 
56
81
class LaunchpadService(object):
57
82
    """A service to talk to Launchpad via XMLRPC.
58
83
 
59
 
    See http://bazaar-vcs.org/Specs/LaunchpadRpc for the methods we can call.
 
84
    See http://wiki.bazaar.canonical.com/Specs/LaunchpadRpc for the methods we can call.
60
85
    """
61
86
 
62
87
    LAUNCHPAD_DOMAINS = {
90
115
        self._lp_instance = lp_instance
91
116
        if transport is None:
92
117
            uri_type = urllib.splittype(self.service_url)[0]
93
 
            if uri_type == 'https':
94
 
                transport = xmlrpclib.SafeTransport()
95
 
            else:
96
 
                transport = xmlrpclib.Transport()
 
118
            transport = XMLRPCTransport(uri_type)
97
119
            transport.user_agent = 'bzr/%s (xmlrpclib/%s)' \
98
120
                    % (_bzrlib_version, xmlrpclib.__version__)
99
121
        self.transport = transport
100
122
 
101
 
 
102
123
    @property
103
124
    def service_url(self):
104
125
        """Return the http or https url for the xmlrpc server.
116
137
        else:
117
138
            return self.DEFAULT_SERVICE_URL
118
139
 
 
140
    @classmethod
 
141
    def for_url(cls, url, **kwargs):
 
142
        """Return the Launchpad service corresponding to the given URL."""
 
143
        result = urlsplit(url)
 
144
        lp_instance = result[1]
 
145
        if lp_instance == '':
 
146
            lp_instance = None
 
147
        elif lp_instance not in cls.LAUNCHPAD_INSTANCE:
 
148
            raise errors.InvalidURL(path=url)
 
149
        return cls(lp_instance=lp_instance, **kwargs)
 
150
 
119
151
    def get_proxy(self, authenticated):
120
152
        """Return the proxy for XMLRPC requests."""
121
153
        if authenticated:
177
209
                # TODO: print more headers to help in tracking down failures
178
210
                raise errors.BzrError("xmlrpc protocol error connecting to %s: %s %s"
179
211
                        % (self.service_url, e.errcode, e.errmsg))
 
212
        except socket.gaierror, e:
 
213
            raise errors.ConnectionError(
 
214
                "Could not resolve '%s'" % self.domain,
 
215
                orig_error=e)
180
216
        return result
181
217
 
182
218
    @property
187
223
            instance = self._lp_instance
188
224
        return self.LAUNCHPAD_DOMAINS[instance]
189
225
 
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
 
        """
 
226
    def _guess_branch_path(self, branch_url, _request_factory=None):
197
227
        scheme, hostinfo, path = urlsplit(branch_url)[:3]
198
228
        if _request_factory is None:
199
229
            _request_factory = ResolveLaunchpadPathRequest
211
241
                for domain in self.LAUNCHPAD_DOMAINS.itervalues())
212
242
            if hostinfo not in domains:
213
243
                raise NotLaunchpadBranch(branch_url)
 
244
        return path.lstrip('/')
 
245
 
 
246
    def get_web_url_from_branch_url(self, branch_url, _request_factory=None):
 
247
        """Get the Launchpad web URL for the given branch URL.
 
248
 
 
249
        :raise errors.InvalidURL: if 'branch_url' cannot be identified as a
 
250
            Launchpad branch URL.
 
251
        :return: The URL of the branch on Launchpad.
 
252
        """
 
253
        path = self._guess_branch_path(branch_url, _request_factory)
214
254
        return urlutils.join('https://code.%s' % self.domain, path)
215
255
 
216
256
 
314
354
    def __init__(self, path):
315
355
        if not path:
316
356
            raise errors.InvalidURL(path=path,
317
 
                                    extra="You must specify a product.")
 
357
                                    extra="You must specify a project.")
318
358
        self.path = path
319
359
 
320
360
    def _request_params(self):