~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

NEWS section template into a separate file

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
 
18
 
from getpass import getpass
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
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
 
24
29
from bzrlib import (
25
30
    config,
26
31
    errors,
40
45
        errors.BzrError.__init__(self, lp_instance=lp_instance)
41
46
 
42
47
 
 
48
class NotLaunchpadBranch(errors.BzrError):
 
49
 
 
50
    _fmt = "%(url)s is not registered on Launchpad."
 
51
 
 
52
    def __init__(self, url):
 
53
        errors.BzrError.__init__(self, url=url)
 
54
 
 
55
 
43
56
class LaunchpadService(object):
44
57
    """A service to talk to Launchpad via XMLRPC.
45
58
 
46
59
    See http://bazaar-vcs.org/Specs/LaunchpadRpc for the methods we can call.
47
60
    """
48
61
 
 
62
    LAUNCHPAD_DOMAINS = {
 
63
        'production': 'launchpad.net',
 
64
        'edge': 'edge.launchpad.net',
 
65
        'staging': 'staging.launchpad.net',
 
66
        'demo': 'demo.launchpad.net',
 
67
        'dev': 'launchpad.dev',
 
68
        }
 
69
 
49
70
    # NB: these should always end in a slash to avoid xmlrpclib appending
50
71
    # '/RPC2'
 
72
    LAUNCHPAD_INSTANCE = {}
 
73
    for instance, domain in LAUNCHPAD_DOMAINS.iteritems():
 
74
        LAUNCHPAD_INSTANCE[instance] = 'https://xmlrpc.%s/bazaar/' % domain
 
75
 
51
76
    # We use edge as the default because:
52
77
    # Beta users get redirected to it
53
78
    # All users can use it
54
79
    # There is a bug in the launchpad side where redirection causes an OOPS.
55
 
    LAUNCHPAD_INSTANCE = {
56
 
        'production': 'https://xmlrpc.launchpad.net/bazaar/',
57
 
        'edge': 'https://xmlrpc.edge.launchpad.net/bazaar/',
58
 
        'staging': 'https://xmlrpc.staging.launchpad.net/bazaar/',
59
 
        'demo': 'https://xmlrpc.demo.launchpad.net/bazaar/',
60
 
        'dev': 'http://xmlrpc.launchpad.dev/bazaar/',
61
 
        }
62
 
    DEFAULT_SERVICE_URL = LAUNCHPAD_INSTANCE['edge']
 
80
    DEFAULT_INSTANCE = 'edge'
 
81
    DEFAULT_SERVICE_URL = LAUNCHPAD_INSTANCE[DEFAULT_INSTANCE]
63
82
 
64
83
    transport = None
65
84
    registrant_email = None
158
177
                # TODO: print more headers to help in tracking down failures
159
178
                raise errors.BzrError("xmlrpc protocol error connecting to %s: %s %s"
160
179
                        % (self.service_url, e.errcode, e.errmsg))
 
180
        except socket.gaierror, e:
 
181
            raise errors.ConnectionError(
 
182
                "Could not resolve '%s'" % self.domain,
 
183
                orig_error=e)
161
184
        return result
162
185
 
 
186
    @property
 
187
    def domain(self):
 
188
        if self._lp_instance is None:
 
189
            instance = self.DEFAULT_INSTANCE
 
190
        else:
 
191
            instance = self._lp_instance
 
192
        return self.LAUNCHPAD_DOMAINS[instance]
 
193
 
 
194
    def get_web_url_from_branch_url(self, branch_url, _request_factory=None):
 
195
        """Get the Launchpad web URL for the given branch URL.
 
196
 
 
197
        :raise errors.InvalidURL: if 'branch_url' cannot be identified as a
 
198
            Launchpad branch URL.
 
199
        :return: The URL of the branch on Launchpad.
 
200
        """
 
201
        scheme, hostinfo, path = urlsplit(branch_url)[:3]
 
202
        if _request_factory is None:
 
203
            _request_factory = ResolveLaunchpadPathRequest
 
204
        if scheme == 'lp':
 
205
            resolve = _request_factory(path)
 
206
            try:
 
207
                result = resolve.submit(self)
 
208
            except xmlrpclib.Fault, fault:
 
209
                raise errors.InvalidURL(branch_url, str(fault))
 
210
            branch_url = result['urls'][0]
 
211
            path = urlsplit(branch_url)[2]
 
212
        else:
 
213
            domains = (
 
214
                'bazaar.%s' % domain
 
215
                for domain in self.LAUNCHPAD_DOMAINS.itervalues())
 
216
            if hostinfo not in domains:
 
217
                raise NotLaunchpadBranch(branch_url)
 
218
        return urlutils.join('https://code.%s' % self.domain, path)
 
219
 
163
220
 
164
221
class BaseRequest(object):
165
222
    """Base request for talking to a XMLRPC server."""
184
241
 
185
242
class DryRunLaunchpadService(LaunchpadService):
186
243
    """Service that just absorbs requests without sending to server.
187
 
    
 
244
 
188
245
    The dummy service does not need authentication.
189
246
    """
190
247
 
261
318
    def __init__(self, path):
262
319
        if not path:
263
320
            raise errors.InvalidURL(path=path,
264
 
                                    extra="You must specify a product.")
 
321
                                    extra="You must specify a project.")
265
322
        self.path = path
266
323
 
267
324
    def _request_params(self):