/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
411 by Martin Pool
- start adding more useful RemoteBranch() class
1
#! /usr/bin/env python
2
188 by mbp at sourcefrog
- experimental remote-branch support
3
# Copyright (C) 2005 Canonical Ltd
4
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
20
"""Proxy object for access to remote branches.
21
22
At the moment remote branches are only for HTTP and only for read
23
access.
24
25
"""
26
27
28
import gzip
192 by mbp at sourcefrog
- exercise the network more towards doing a remote clone
29
from sets import Set
30
from cStringIO import StringIO
188 by mbp at sourcefrog
- experimental remote-branch support
31
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
32
from errors import BzrError, BzrCheckError
411 by Martin Pool
- start adding more useful RemoteBranch() class
33
from branch import Branch
188 by mbp at sourcefrog
- experimental remote-branch support
34
193 by mbp at sourcefrog
more experiments with http get
35
# velocitynet.com.au transparently proxies connections and thereby
36
# breaks keep-alive -- sucks!
37
38
39
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
40
ENABLE_URLGRABBER = False
41
42
def get_url(url, compressed=False):
43
    import urllib2
44
    if compressed:
45
        url += '.gz'
46
    url_f = urllib2.urlopen(url)
47
    if compressed:
48
        return gzip.GzipFile(fileobj=StringIO(url_f.read()))
49
    else:
50
        return url_f
51
52
if ENABLE_URLGRABBER:
53
    import urlgrabber
54
    import urlgrabber.keepalive
55
    urlgrabber.keepalive.DEBUG = 0
56
    def get_url(path, compressed=False):
57
        try:
58
            url = path
59
            if compressed:
60
                url += '.gz'
61
            url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
62
            if not compressed:
63
                return url_f
64
            else:
65
                return gzip.GzipFile(fileobj=StringIO(url_f.read()))
66
        except urllib2.URLError, e:
67
            raise BzrError("remote fetch failed: %r: %s" % (url, e))
188 by mbp at sourcefrog
- experimental remote-branch support
68
192 by mbp at sourcefrog
- exercise the network more towards doing a remote clone
69
416 by Martin Pool
- bzr log and bzr root now accept an http URL
70
71
def _find_remote_root(url):
72
    """Return the prefix URL that corresponds to the branch root."""
73
    orig_url = url
74
    while True:
75
        try:
76
            ff = get_url(url + '/.bzr/branch-format')
77
            ff.close()
78
            return url
79
        except urllib.URLError:
80
            pass
81
82
        try:
83
            idx = url.rindex('/')
84
        except ValueError:
85
            raise BzrError('no branch root found for URL %s' % orig_url)
86
87
        url = url[:idx]        
88
        
89
90
411 by Martin Pool
- start adding more useful RemoteBranch() class
91
class RemoteBranch(Branch):
416 by Martin Pool
- bzr log and bzr root now accept an http URL
92
    def __init__(self, baseurl, find_root=False, lock_mode='r'):
411 by Martin Pool
- start adding more useful RemoteBranch() class
93
        """Create new proxy for a remote branch."""
416 by Martin Pool
- bzr log and bzr root now accept an http URL
94
        if lock_mode not in ('', 'r'):
95
            raise BzrError('lock mode %r is not supported for remote branches'
96
                           % lock_mode)
97
        
411 by Martin Pool
- start adding more useful RemoteBranch() class
98
        self.baseurl = baseurl
99
        self._check_format()
100
101
    def controlfile(self, filename, mode):
102
        if mode not in ('rb', 'rt', 'r'):
103
            raise BzrError("file mode %r not supported for remote branches" % mode)
104
        return get_url(self.baseurl + '/.bzr/' + filename, False)
105
106
    def _need_readlock(self):
107
        # remote branch always safe for read
108
        pass
109
110
    def _need_writelock(self):
111
        raise BzrError("cannot get write lock on HTTP remote branch")
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
112
416 by Martin Pool
- bzr log and bzr root now accept an http URL
113
    def relpath(self, path):
114
        if not path.startswith(self.baseurl):
115
            raise BzrError('path %r is not under base URL %r'
116
                           % (path, self.baseurl))
117
        pl = len(self.baseurl)
118
        return path[pl:].lstrip('/')
119
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
120
    def get_revision(self, revision_id):
121
        from revision import Revision
122
        revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
123
                       True)
124
        r = Revision.read_xml(revf)
125
        if r.revision_id != revision_id:
126
            raise BzrCheckError('revision stored as {%s} actually contains {%s}'
127
                                % (revision_id, r.revision_id))
128
        return r
188 by mbp at sourcefrog
- experimental remote-branch support
129
    
411 by Martin Pool
- start adding more useful RemoteBranch() class
130
131
def simple_walk():
413 by Martin Pool
- more indicators at top of test output
132
    from revision import Revision
133
    from branch import Branch
134
    from inventory import Inventory
135
411 by Martin Pool
- start adding more useful RemoteBranch() class
136
    got_invs = Set()
137
    got_texts = Set()
138
139
    print 'read history'
140
    history = get_url('/.bzr/revision-history').readlines()
141
    num_revs = len(history)
142
    for i, rev_id in enumerate(history):
143
        rev_id = rev_id.rstrip()
144
        print 'read revision %d/%d' % (i, num_revs)
145
146
        # python gzip needs a seekable file (!!) but the HTTP response
147
        # isn't, so we need to buffer it
148
149
        rev_f = get_url('/.bzr/revision-store/%s' % rev_id,
192 by mbp at sourcefrog
- exercise the network more towards doing a remote clone
150
                        compressed=True)
411 by Martin Pool
- start adding more useful RemoteBranch() class
151
152
        rev = Revision.read_xml(rev_f)
153
        print rev.message
154
        inv_id = rev.inventory_id
155
        if inv_id not in got_invs:
156
            print 'get inventory %s' % inv_id
157
            inv_f = get_url('/.bzr/inventory-store/%s' % inv_id,
158
                            compressed=True)
159
            inv = Inventory.read_xml(inv_f)
160
            print '%4d inventory entries' % len(inv)
161
162
            for path, ie in inv.iter_entries():
163
                text_id = ie.text_id
164
                if text_id == None:
165
                    continue
166
                if text_id in got_texts:
167
                    continue
168
                print '  fetch %s text {%s}' % (path, text_id)
169
                text_f = get_url('/.bzr/text-store/%s' % text_id,
170
                                 compressed=True)
171
                got_texts.add(text_id)
172
173
            got_invs.add(inv_id)
174
175
        print '----'
176
177
178
def try_me():
413 by Martin Pool
- more indicators at top of test output
179
    BASE_URL = 'http://bazaar-ng.org/bzr/bzr.dev/'
411 by Martin Pool
- start adding more useful RemoteBranch() class
180
    b = RemoteBranch(BASE_URL)
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
181
    ## print '\n'.join(b.revision_history())
182
    from log import show_log
183
    show_log(b)
411 by Martin Pool
- start adding more useful RemoteBranch() class
184
185
186
if __name__ == '__main__':
187
    try_me()
188