/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 08:27:49 UTC
  • Revision ID: mbp@sourcefrog.net-20050509082749-22b1a6f4af329f7b
- bzr log and bzr root now accept an http URL
- new RemoteBranch.relpath()
- new find_branch factory method

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
68
 
80
69
 
81
70
 
85
74
    while True:
86
75
        try:
87
76
            ff = get_url(url + '/.bzr/branch-format')
88
 
 
89
 
            fmt = ff.read()
90
77
            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
78
            return url
98
 
        except urllib2.URLError:
 
79
        except urllib.URLError:
99
80
            pass
100
81
 
101
82
        try:
108
89
 
109
90
 
110
91
class RemoteBranch(Branch):
111
 
    def __init__(self, baseurl, find_root=True):
 
92
    def __init__(self, baseurl, find_root=False, lock_mode='r'):
112
93
        """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__
 
94
        if lock_mode not in ('', 'r'):
 
95
            raise BzrError('lock mode %r is not supported for remote branches'
 
96
                           % lock_mode)
 
97
        
 
98
        self.baseurl = baseurl
 
99
        self._check_format()
128
100
 
129
101
    def controlfile(self, filename, mode):
130
102
        if mode not in ('rb', 'rt', 'r'):
131
103
            raise BzrError("file mode %r not supported for remote branches" % mode)
132
104
        return get_url(self.baseurl + '/.bzr/' + filename, False)
133
105
 
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
 
    
 
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")
147
112
 
148
113
    def relpath(self, path):
149
114
        if not path.startswith(self.baseurl):
152
117
        pl = len(self.baseurl)
153
118
        return path[pl:].lstrip('/')
154
119
 
155
 
 
156
120
    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)
 
121
        from revision import Revision
 
122
        revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
 
123
                       True)
 
124
        r = Revision.read_xml(revf)
161
125
        if r.revision_id != revision_id:
162
126
            raise BzrCheckError('revision stored as {%s} actually contains {%s}'
163
127
                                % (revision_id, r.revision_id))
164
128
        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
129
    
184
130
 
 
131
def simple_walk():
 
132
    from revision import Revision
 
133
    from branch import Branch
 
134
    from inventory import Inventory
 
135
 
 
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,
 
150
                        compressed=True)
 
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():
 
179
    BASE_URL = 'http://bazaar-ng.org/bzr/bzr.dev/'
 
180
    b = RemoteBranch(BASE_URL)
 
181
    ## print '\n'.join(b.revision_history())
 
182
    from log import show_log
 
183
    show_log(b)
 
184
 
 
185
 
 
186
if __name__ == '__main__':
 
187
    try_me()
185
188