3
# Copyright (C) 2005 Canonical Ltd
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.
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.
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
20
"""Proxy object for access to remote branches.
22
At the moment remote branches are only for HTTP and only for read
30
from cStringIO import StringIO
32
from errors import BzrError, BzrCheckError
33
from branch import Branch
35
# velocitynet.com.au transparently proxies connections and thereby
36
# breaks keep-alive -- sucks!
40
ENABLE_URLGRABBER = False
42
def get_url(url, compressed=False):
46
url_f = urllib2.urlopen(url)
48
return gzip.GzipFile(fileobj=StringIO(url_f.read()))
54
import urlgrabber.keepalive
55
urlgrabber.keepalive.DEBUG = 0
56
def get_url(path, compressed=False):
61
url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
65
return gzip.GzipFile(fileobj=StringIO(url_f.read()))
66
except urllib2.URLError, e:
67
raise BzrError("remote fetch failed: %r: %s" % (url, e))
71
def _find_remote_root(url):
72
"""Return the prefix URL that corresponds to the branch root."""
76
ff = get_url(url + '/.bzr/branch-format')
79
except urllib.URLError:
85
raise BzrError('no branch root found for URL %s' % orig_url)
91
class RemoteBranch(Branch):
92
def __init__(self, baseurl, find_root=False, lock_mode='r'):
93
"""Create new proxy for a remote branch."""
94
if lock_mode not in ('', 'r'):
95
raise BzrError('lock mode %r is not supported for remote branches'
98
self.baseurl = baseurl
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)
106
def _need_readlock(self):
107
# remote branch always safe for read
110
def _need_writelock(self):
111
raise BzrError("cannot get write lock on HTTP remote branch")
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('/')
120
def get_revision(self, revision_id):
121
from revision import Revision
122
revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
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))
132
from revision import Revision
133
from branch import Branch
134
from inventory import Inventory
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)
146
# python gzip needs a seekable file (!!) but the HTTP response
147
# isn't, so we need to buffer it
149
rev_f = get_url('/.bzr/revision-store/%s' % rev_id,
152
rev = Revision.read_xml(rev_f)
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,
159
inv = Inventory.read_xml(inv_f)
160
print '%4d inventory entries' % len(inv)
162
for path, ie in inv.iter_entries():
166
if text_id in got_texts:
168
print ' fetch %s text {%s}' % (path, text_id)
169
text_f = get_url('/.bzr/text-store/%s' % text_id,
171
got_texts.add(text_id)
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
186
if __name__ == '__main__':