161
161
return self._combine_paths(self._path, relpath)
163
163
def _call(self, method, *args):
165
resp = self._call2(method, *args)
166
except errors.ErrorFromSmartServer, err:
167
self._translate_error(err.error_tuple)
168
self._translate_error(resp)
164
resp = self._call2(method, *args)
165
self._ensure_ok(resp)
170
167
def _call2(self, method, *args):
171
168
"""Call a method on the remote server."""
173
170
return self._client.call(method, *args)
174
171
except errors.ErrorFromSmartServer, err:
175
self._translate_error(err.error_tuple)
172
self._translate_error(err)
177
174
def _call_with_body_bytes(self, method, args, body):
178
175
"""Call a method on the remote server with body bytes."""
180
177
return self._client.call_with_body_bytes(method, args, body)
181
178
except errors.ErrorFromSmartServer, err:
182
self._translate_error(err.error_tuple)
179
self._translate_error(err)
184
181
def has(self, relpath):
185
182
"""Indicate whether a remote file of the given name exists or not.
207
204
resp, response_handler = self._client.call_expecting_body('get', remote)
208
205
except errors.ErrorFromSmartServer, err:
209
self._translate_error(err.error_tuple, relpath)
206
self._translate_error(err, relpath)
210
207
if resp != ('ok', ):
211
208
response_handler.cancel_read_body()
212
209
raise errors.UnexpectedSmartServerResponse(resp)
221
218
def mkdir(self, relpath, mode=None):
222
219
resp = self._call2('mkdir', self._remote_path(relpath),
223
220
self._serialise_optional_mode(mode))
224
self._translate_error(resp)
226
222
def open_write_stream(self, relpath, mode=None):
227
223
"""See Transport.open_write_stream."""
243
239
resp = self._call_with_body_bytes('put',
244
240
(self._remote_path(relpath), self._serialise_optional_mode(mode)),
246
self._translate_error(resp)
242
self._ensure_ok(resp)
247
243
return len(upload_contents)
249
245
def put_bytes_non_atomic(self, relpath, bytes, mode=None,
260
256
(self._remote_path(relpath), self._serialise_optional_mode(mode),
261
257
create_parent_str, self._serialise_optional_mode(dir_mode)),
263
self._translate_error(resp)
259
self._ensure_ok(resp)
265
261
def put_file(self, relpath, upload_file, mode=None):
266
262
# its not ideal to seek back, but currently put_non_atomic_file depends
291
287
if resp[0] == 'appended':
292
288
return int(resp[1])
293
self._translate_error(resp)
289
raise errors.UnexpectedSmartServerResponse(resp)
295
291
def delete(self, relpath):
296
292
resp = self._call2('delete', self._remote_path(relpath))
297
self._translate_error(resp)
293
self._ensure_ok(resp)
299
295
def external_url(self):
300
296
"""See bzrlib.transport.Transport.external_url."""
322
318
[(c.start, c.length) for c in coalesced])
323
319
resp, response_handler = result
324
320
except errors.ErrorFromSmartServer, err:
325
self._translate_error(err.error_tuple)
321
self._translate_error(err)
327
323
if resp[0] != 'readv':
328
324
# This should raise an exception
381
377
def rmdir(self, relpath):
382
378
resp = self._call('rmdir', self._remote_path(relpath))
384
def _translate_error(self, resp, orig_path=None):
385
"""Raise an exception from a response"""
392
elif what == 'NoSuchFile':
393
if orig_path is not None:
394
error_path = orig_path
397
raise errors.NoSuchFile(error_path)
398
elif what == 'error':
399
raise errors.SmartProtocolError(unicode(resp[1]))
400
elif what == 'FileExists':
401
raise errors.FileExists(resp[1])
402
elif what == 'DirectoryNotEmpty':
403
raise errors.DirectoryNotEmpty(resp[1])
404
elif what == 'ShortReadvError':
405
raise errors.ShortReadvError(resp[1], int(resp[2]),
406
int(resp[3]), int(resp[4]))
407
elif what in ('UnicodeEncodeError', 'UnicodeDecodeError'):
408
encoding = str(resp[1]) # encoding must always be a string
412
reason = str(resp[5]) # reason must always be a string
413
if val.startswith('u:'):
414
val = val[2:].decode('utf-8')
415
elif val.startswith('s:'):
416
val = val[2:].decode('base64')
417
if what == 'UnicodeDecodeError':
418
raise UnicodeDecodeError(encoding, val, start, end, reason)
419
elif what == 'UnicodeEncodeError':
420
raise UnicodeEncodeError(encoding, val, start, end, reason)
421
elif what == "ReadOnlyError":
422
raise errors.TransportNotPossible('readonly transport')
423
elif what == "ReadError":
424
if orig_path is not None:
425
error_path = orig_path
428
raise errors.ReadError(error_path)
429
elif what == "PermissionDenied":
430
if orig_path is not None:
431
error_path = orig_path
434
raise errors.PermissionDenied(error_path)
436
raise errors.SmartProtocolError('unexpected smart server error: %r' % (resp,))
380
def _ensure_ok(self, resp):
382
raise errors.UnexpectedSmartServerResponse(resp)
384
def _translate_error(self, err, orig_path=None):
385
remote._translate_error(err, path=orig_path)
438
387
def disconnect(self):
439
388
self.get_smart_medium().disconnect()
442
391
resp = self._call2('stat', self._remote_path(relpath))
443
392
if resp[0] == 'stat':
444
393
return _SmartStat(int(resp[1]), int(resp[2], 8))
446
self._translate_error(resp)
394
raise errors.UnexpectedSmartServerResponse(resp)
448
396
## def lock_read(self, relpath):
449
397
## """Lock the given file for shared (read) access.
465
413
resp = self._call2('list_dir', self._remote_path(relpath))
466
414
if resp[0] == 'names':
467
415
return [name.encode('ascii') for name in resp[1:]]
469
self._translate_error(resp)
416
raise errors.UnexpectedSmartServerResponse(resp)
471
418
def iter_files_recursive(self):
472
419
resp = self._call2('iter_files_recursive', self._remote_path(''))
473
420
if resp[0] == 'names':
476
self._translate_error(resp)
422
raise errors.UnexpectedSmartServerResponse(resp)
479
425
class RemoteTCPTransport(RemoteTransport):