/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/remotebranch.py

  • Committer: Martin Pool
  • Date: 2005-05-09 06:22:29 UTC
  • Revision ID: mbp@sourcefrog.net-20050509062229-447396ed497a15dd
todo

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
At the moment remote branches are only for HTTP and only for read
23
23
access.
 
24
 
24
25
"""
25
26
 
26
27
 
27
28
import gzip
 
29
from sets import Set
28
30
from cStringIO import StringIO
29
 
import urllib2
30
31
 
31
32
from errors import BzrError, BzrCheckError
32
 
from branch import Branch, BZR_BRANCH_FORMAT
33
 
from trace import mutter
 
33
from branch import Branch
34
34
 
35
35
# velocitynet.com.au transparently proxies connections and thereby
36
36
# breaks keep-alive -- sucks!
37
37
 
38
38
 
39
 
ENABLE_URLGRABBER = True
40
 
 
41
 
from bzrlib.errors import BzrError
42
 
 
43
 
class GetFailed(BzrError):
44
 
    def __init__(self, url, status):
45
 
        BzrError.__init__(self, "Get %s failed with status %s" % (url, status))
46
 
        self.url = url
47
 
        self.status = status
 
39
 
 
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
48
51
 
49
52
if ENABLE_URLGRABBER:
50
53
    import urlgrabber
55
58
            url = path
56
59
            if compressed:
57
60
                url += '.gz'
58
 
            mutter("grab url %s" % url)
59
61
            url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
60
 
            if url_f.status != 200:
61
 
                raise GetFailed(url, url_f.status)
62
62
            if not compressed:
63
63
                return url_f
64
64
            else:
65
65
                return gzip.GzipFile(fileobj=StringIO(url_f.read()))
66
66
        except urllib2.URLError, e:
67
67
            raise BzrError("remote fetch failed: %r: %s" % (url, e))
68
 
else:
69
 
    def get_url(url, compressed=False):
70
 
        import urllib2
71
 
        if compressed:
72
 
            url += '.gz'
73
 
        mutter("get_url %s" % url)
74
 
        url_f = urllib2.urlopen(url)
75
 
        if compressed:
76
 
            return gzip.GzipFile(fileobj=StringIO(url_f.read()))
77
 
        else:
78
 
            return url_f
79
 
 
80
 
 
81
 
 
82
 
def _find_remote_root(url):
83
 
    """Return the prefix URL that corresponds to the branch root."""
84
 
    orig_url = url
85
 
    while True:
86
 
        try:
87
 
            ff = get_url(url + '/.bzr/branch-format')
88
 
 
89
 
            fmt = ff.read()
90
 
            ff.close()
91
 
 
92
 
            fmt = fmt.rstrip('\r\n')
93
 
            if fmt != BZR_BRANCH_FORMAT.rstrip('\r\n'):
94
 
                raise BzrError("sorry, branch format %r not supported at url %s"
95
 
                               % (fmt, url))
96
 
            
97
 
            return url
98
 
        except urllib2.URLError:
99
 
            pass
100
 
 
101
 
        try:
102
 
            idx = url.rindex('/')
103
 
        except ValueError:
104
 
            raise BzrError('no branch root found for URL %s' % orig_url)
105
 
 
106
 
        url = url[:idx]        
107
 
        
108
68
 
109
69
 
110
70
class RemoteBranch(Branch):
111
 
    def __init__(self, baseurl, find_root=True):
 
71
    def __init__(self, baseurl):
112
72
        """Create new proxy for a remote branch."""
113
 
        if find_root:
114
 
            self.baseurl = _find_remote_root(baseurl)
115
 
        else:
116
 
            self.baseurl = baseurl
117
 
            self._check_format()
118
 
 
119
 
        self.inventory_store = RemoteStore(baseurl + '/.bzr/inventory-store/')
120
 
        self.text_store = RemoteStore(baseurl + '/.bzr/text-store/')
121
 
        self.revision_store = RemoteStore(baseurl + '/.bzr/revision-store/')
122
 
 
123
 
    def __str__(self):
124
 
        b = getattr(self, 'baseurl', 'undefined')
125
 
        return '%s(%r)' % (self.__class__.__name__, b)
126
 
 
127
 
    __repr__ = __str__
 
73
        self.baseurl = baseurl
 
74
        self._check_format()
128
75
 
129
76
    def controlfile(self, filename, mode):
130
77
        if mode not in ('rb', 'rt', 'r'):
131
78
            raise BzrError("file mode %r not supported for remote branches" % mode)
132
79
        return get_url(self.baseurl + '/.bzr/' + filename, False)
133
80
 
134
 
 
135
 
    def lock_read(self):
136
 
        # no locking for remote branches yet
137
 
        pass
138
 
 
139
 
    def lock_write(self):
140
 
        from errors import LockError
141
 
        raise LockError("write lock not supported for remote branch %s"
142
 
                        % self.baseurl)
143
 
 
144
 
    def unlock(self):
145
 
        pass
146
 
    
147
 
 
148
 
    def relpath(self, path):
149
 
        if not path.startswith(self.baseurl):
150
 
            raise BzrError('path %r is not under base URL %r'
151
 
                           % (path, self.baseurl))
152
 
        pl = len(self.baseurl)
153
 
        return path[pl:].lstrip('/')
154
 
 
 
81
    def _need_readlock(self):
 
82
        # remote branch always safe for read
 
83
        pass
 
84
 
 
85
    def _need_writelock(self):
 
86
        raise BzrError("cannot get write lock on HTTP remote branch")
155
87
 
156
88
    def get_revision(self, revision_id):
157
 
        from bzrlib.revision import Revision
158
 
        from bzrlib.xml import unpack_xml
159
 
        revf = self.revision_store[revision_id]
160
 
        r = unpack_xml(Revision, revf)
 
89
        from revision import Revision
 
90
        revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
 
91
                       True)
 
92
        r = Revision.read_xml(revf)
161
93
        if r.revision_id != revision_id:
162
94
            raise BzrCheckError('revision stored as {%s} actually contains {%s}'
163
95
                                % (revision_id, r.revision_id))
164
96
        return r
165
 
 
166
 
 
167
 
class RemoteStore(object):
168
 
    def __init__(self, baseurl):
169
 
        self._baseurl = baseurl
170
 
        
171
 
 
172
 
    def _path(self, name):
173
 
        if '/' in name:
174
 
            raise ValueError('invalid store id', name)
175
 
        return self._baseurl + '/' + name
176
 
        
177
 
    def __getitem__(self, fileid):
178
 
        p = self._path(fileid)
179
 
        try:
180
 
            return get_url(p, compressed=True)
181
 
        except:
182
 
            raise KeyError(fileid)
183
97
    
184
98
 
 
99
def simple_walk():
 
100
    from revision import Revision
 
101
    from branch import Branch
 
102
    from inventory import Inventory
 
103
 
 
104
    got_invs = Set()
 
105
    got_texts = Set()
 
106
 
 
107
    print 'read history'
 
108
    history = get_url('/.bzr/revision-history').readlines()
 
109
    num_revs = len(history)
 
110
    for i, rev_id in enumerate(history):
 
111
        rev_id = rev_id.rstrip()
 
112
        print 'read revision %d/%d' % (i, num_revs)
 
113
 
 
114
        # python gzip needs a seekable file (!!) but the HTTP response
 
115
        # isn't, so we need to buffer it
 
116
 
 
117
        rev_f = get_url('/.bzr/revision-store/%s' % rev_id,
 
118
                        compressed=True)
 
119
 
 
120
        rev = Revision.read_xml(rev_f)
 
121
        print rev.message
 
122
        inv_id = rev.inventory_id
 
123
        if inv_id not in got_invs:
 
124
            print 'get inventory %s' % inv_id
 
125
            inv_f = get_url('/.bzr/inventory-store/%s' % inv_id,
 
126
                            compressed=True)
 
127
            inv = Inventory.read_xml(inv_f)
 
128
            print '%4d inventory entries' % len(inv)
 
129
 
 
130
            for path, ie in inv.iter_entries():
 
131
                text_id = ie.text_id
 
132
                if text_id == None:
 
133
                    continue
 
134
                if text_id in got_texts:
 
135
                    continue
 
136
                print '  fetch %s text {%s}' % (path, text_id)
 
137
                text_f = get_url('/.bzr/text-store/%s' % text_id,
 
138
                                 compressed=True)
 
139
                got_texts.add(text_id)
 
140
 
 
141
            got_invs.add(inv_id)
 
142
 
 
143
        print '----'
 
144
 
 
145
 
 
146
def try_me():
 
147
    BASE_URL = 'http://bazaar-ng.org/bzr/bzr.dev/'
 
148
    b = RemoteBranch(BASE_URL)
 
149
    ## print '\n'.join(b.revision_history())
 
150
    from log import show_log
 
151
    show_log(b)
 
152
 
 
153
 
 
154
if __name__ == '__main__':
 
155
    try_me()
185
156