/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
1
# Copyright (C) 2006-2010 Canonical Ltd
2
# Copyright (C) 2018 Breezy Developers
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18
"""UI location string handling."""
19
7265.6.2 by Jelmer Vernooij
Support rsync-style URLs.
20
import re
21
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
22
from . import (
23
    urlutils,
24
    )
7268.11.1 by Jelmer Vernooij
Add rewrite_url hook.
25
from .hooks import Hooks
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
26
27
7268.11.1 by Jelmer Vernooij
Add rewrite_url hook.
28
class LocationHooks(Hooks):
29
    """Dictionary mapping hook name to a list of callables for location hooks.
30
    """
31
32
    def __init__(self):
33
        Hooks.__init__(self, "breezy.location", "hooks")
34
        self.add_hook(
35
            'rewrite_url',
7268.11.2 by Jelmer Vernooij
Add purpose argument.
36
            "Possibly rewrite a URL. Called with a URL to rewrite and the "
37
            "purpose of the URL.", (3, 0))
7268.11.1 by Jelmer Vernooij
Add rewrite_url hook.
38
39
40
hooks = LocationHooks()
41
7490.75.1 by Jelmer Vernooij
some refactoring.
42
def parse_rcp_location(location):
7265.6.2 by Jelmer Vernooij
Support rsync-style URLs.
43
    """Convert a rcp-style location to a URL.
44
45
    :param location: Location to convert, e.g. "foo:bar"
7490.75.1 by Jelmer Vernooij
some refactoring.
46
    :param scheme: URL scheme to return, defaults to "ssh"
7265.6.2 by Jelmer Vernooij
Support rsync-style URLs.
47
    :return: A URL, e.g. "ssh://foo/bar"
48
    :raises ValueError: if this is not a RCP-style URL
49
    """
50
    m = re.match('^(?P<user>[^@:/]+@)?(?P<host>[^/:]+):(?P<path>.*)$', location)
51
    if not m:
52
        raise ValueError("Not a RCP URL")
53
    if m.group('path').startswith('//'):
54
        raise ValueError("Not a RCP URL: already looks like a URL")
7490.75.1 by Jelmer Vernooij
some refactoring.
55
    return (m.group('host'),
56
            m.group('user')[:-1] if m.group('user') else None,
57
            m.group('path'))
58
59
60
def rcp_location_to_url(location, scheme='ssh'):
61
    """Convert a rcp-style location to a URL.
62
63
    :param location: Location to convert, e.g. "foo:bar"
64
    :param scheme: URL scheme to return, defaults to "ssh"
65
    :return: A URL, e.g. "ssh://foo/bar"
66
    :raises ValueError: if this is not a RCP-style URL
67
    """
68
    (host, user, path) = parse_rcp_location(location)
69
    quoted_user = urlutils.quote(user) if user else None
7265.6.2 by Jelmer Vernooij
Support rsync-style URLs.
70
    url = urlutils.URL(
71
        scheme=scheme, quoted_user=quoted_user,
72
        port=None, quoted_password=None,
7490.75.1 by Jelmer Vernooij
some refactoring.
73
        quoted_host=urlutils.quote(host),
74
        quoted_path=urlutils.quote(path))
7265.6.2 by Jelmer Vernooij
Support rsync-style URLs.
75
    return str(url)
76
77
7490.75.1 by Jelmer Vernooij
some refactoring.
78
def parse_cvs_location(location):
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
79
    parts = location.split(':')
7490.149.1 by Jelmer Vernooij
Add support for converting extssh CVS URLs.
80
    if parts[0] or parts[1] not in ('pserver', 'ssh', 'extssh'):
81
        raise ValueError('not a valid CVS location string')
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
82
    try:
83
        (username, hostname) = parts[2].split('@', 1)
84
    except IndexError:
85
        hostname = parts[2]
86
        username = None
7490.75.1 by Jelmer Vernooij
some refactoring.
87
    scheme = parts[1]
7490.149.1 by Jelmer Vernooij
Add support for converting extssh CVS URLs.
88
    if scheme == 'extssh':
89
        scheme = 'ssh'
7490.75.1 by Jelmer Vernooij
some refactoring.
90
    path = parts[3]
91
    return (scheme, hostname, username, path)
92
93
94
def cvs_to_url(location):
95
    """Convert a CVS pserver location string to a URL.
96
97
    :param location: pserver URL
98
    :return: A cvs+pserver URL
99
    """
100
    (scheme, host, user, path) = parse_cvs_location(location)
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
101
    return str(urlutils.URL(
7490.75.1 by Jelmer Vernooij
some refactoring.
102
        scheme='cvs+' + scheme,
103
        quoted_user=urlutils.quote(user) if user else None,
104
        quoted_host=urlutils.quote(host),
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
105
        quoted_password=None,
106
        port=None,
7490.75.1 by Jelmer Vernooij
some refactoring.
107
        quoted_path=urlutils.quote(path)))
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
108
109
7268.11.2 by Jelmer Vernooij
Add purpose argument.
110
def location_to_url(location, purpose=None):
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
111
    """Determine a fully qualified URL from a location string.
112
113
    This will try to interpret location as both a URL and a directory path. It
114
    will also lookup the location in directories.
115
116
    :param location: Unicode or byte string object with a location
7268.11.4 by Jelmer Vernooij
Actually pass in purpose in a couple of places.
117
    :param purpose: Intended method of access (None, 'read' or 'write')
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
118
    :raise InvalidURL: If the location is already a URL, but not valid.
119
    :return: Byte string with resulting URL
120
    """
7479.2.1 by Jelmer Vernooij
Drop python2 support.
121
    if not isinstance(location, str):
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
122
        raise AssertionError("location not a byte or unicode string")
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
123
7490.149.1 by Jelmer Vernooij
Add support for converting extssh CVS URLs.
124
    if location.startswith(':pserver:') or location.startswith(':extssh:'):
7490.75.1 by Jelmer Vernooij
some refactoring.
125
        return cvs_to_url(location)
7413.5.1 by Jelmer Vernooij
CVS pserver URLs indicate that the pserver protocol is not supported.
126
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
127
    from .directory_service import directories
7268.11.2 by Jelmer Vernooij
Add purpose argument.
128
    location = directories.dereference(location, purpose)
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
129
130
    # Catch any URLs which are passing Unicode rather than ASCII
131
    try:
132
        location = location.encode('ascii')
133
    except UnicodeError:
134
        if urlutils.is_url(location):
7265.6.1 by Jelmer Vernooij
Reformatting.
135
            raise urlutils.InvalidURL(
136
                path=location, extra='URLs must be properly escaped')
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
137
        location = urlutils.local_path_to_url(location)
138
    else:
7479.2.1 by Jelmer Vernooij
Drop python2 support.
139
        location = location.decode('ascii')
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
140
141
    if location.startswith("file:") and not location.startswith("file://"):
142
        return urlutils.join(urlutils.local_path_to_url("."), location[5:])
143
7265.6.2 by Jelmer Vernooij
Support rsync-style URLs.
144
    try:
145
        url = rcp_location_to_url(location, scheme="ssh")
146
    except ValueError:
147
        pass
148
    else:
149
        return url
150
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
151
    if not urlutils.is_url(location):
152
        return urlutils.local_path_to_url(location)
153
7268.11.1 by Jelmer Vernooij
Add rewrite_url hook.
154
    for hook in hooks['rewrite_url']:
7268.11.2 by Jelmer Vernooij
Add purpose argument.
155
        location = hook(location, purpose=purpose)
7268.11.1 by Jelmer Vernooij
Add rewrite_url hook.
156
7204.2.1 by Jelmer Vernooij
Move location_to_url to its own module.
157
    return location