Revision f89e3cf4
b/pithos/lib/client.py | ||
---|---|---|
294 | 294 |
|
295 | 295 |
def create_container(self, container, headers=None, **meta): |
296 | 296 |
for k,v in meta.items(): |
297 |
headers['X_CONTAINER_META_%s' %k.strip().upper()] = v.strip()
|
|
297 |
headers['X-Container-Meta-%s' %k.strip().upper()] = v.strip()
|
|
298 | 298 |
status, header, data = self.put('/' + container, headers=headers) |
299 | 299 |
if status == 202: |
300 | 300 |
return False |
... | ... | |
342 | 342 |
h = {'Content-Type':'application/directory'} |
343 | 343 |
self.create_object(container, object, f=None, headers=h) |
344 | 344 |
|
345 |
def _set_public(self, headers, public=False): |
|
346 |
""" |
|
347 |
sets the public header |
|
348 |
""" |
|
349 |
if public == None: |
|
350 |
return |
|
351 |
elif public: |
|
352 |
headers['X-Object-Public'] = public |
|
353 |
else: |
|
354 |
headers['X-Object-Public'] = '' |
|
355 |
|
|
345 | 356 |
def create_object(self, container, object, f=stdin, chunked=False, |
346 |
blocksize=1024, headers=None, use_hashes=False, **meta): |
|
357 |
blocksize=1024, headers={}, use_hashes=False, |
|
358 |
public=None, **meta): |
|
347 | 359 |
""" |
348 | 360 |
creates an object |
349 | 361 |
if f is None then creates a zero length object |
... | ... | |
351 | 363 |
""" |
352 | 364 |
path = '/%s/%s' % (container, object) |
353 | 365 |
for k,v in meta.items(): |
354 |
headers['X_OBJECT_META_%s' %k.strip().upper()] = v.strip() |
|
366 |
headers['X-Object-Meta-%s' %k.strip().upper()] = v.strip() |
|
367 |
self._set_public(headers, public) |
|
368 |
headers = headers if headers else None |
|
355 | 369 |
if not chunked: |
356 | 370 |
format = 'json' if use_hashes else 'text' |
357 | 371 |
data = f.read() if f else None |
... | ... | |
365 | 379 |
blocksize=1024) |
366 | 380 |
|
367 | 381 |
def update_object(self, container, object, f=stdin, chunked=False, |
368 |
blocksize=1024, headers=None, offset=None, **meta): |
|
382 |
blocksize=1024, headers={}, offset=None, public=None, |
|
383 |
**meta): |
|
384 |
print locals() |
|
369 | 385 |
path = '/%s/%s' % (container, object) |
370 | 386 |
for k,v in meta.items(): |
371 |
headers['X_OBJECT_META_%s' %k.strip().upper()] = v.strip()
|
|
387 |
headers['X-Object-Meta-%s' %k.strip().upper()] = v.strip()
|
|
372 | 388 |
if offset: |
373 | 389 |
headers['Content-Range'] = 'bytes %s-/*' % offset |
374 | 390 |
else: |
375 | 391 |
headers['Content-Range'] = 'bytes */*' |
376 |
|
|
392 |
self._set_public(headers, public) |
|
393 |
headers = headers if headers else None |
|
377 | 394 |
if not chunked and f != stdin: |
378 | 395 |
data = f.read() if f else None |
379 | 396 |
self.post(path, data, headers=headers) |
... | ... | |
382 | 399 |
blocksize=1024) |
383 | 400 |
|
384 | 401 |
def _change_obj_location(self, src_container, src_object, dst_container, |
385 |
dst_object, remove=False, headers=None):
|
|
402 |
dst_object, remove=False, public=None, headers={}):
|
|
386 | 403 |
path = '/%s/%s' % (dst_container, dst_object) |
387 | 404 |
if not headers: |
388 | 405 |
headers = {} |
... | ... | |
390 | 407 |
headers['X-Move-From'] = '/%s/%s' % (src_container, src_object) |
391 | 408 |
else: |
392 | 409 |
headers['X-Copy-From'] = '/%s/%s' % (src_container, src_object) |
410 |
self._set_public(headers, public) |
|
411 |
self.headers = headers if headers else None |
|
393 | 412 |
headers['Content-Length'] = 0 |
394 | 413 |
self.put(path, headers=headers) |
395 | 414 |
|
396 | 415 |
def copy_object(self, src_container, src_object, dst_container, |
397 |
dst_object, headers=None): |
|
416 |
dst_object, public=False, headers=None):
|
|
398 | 417 |
self._change_obj_location(src_container, src_object, |
399 | 418 |
dst_container, dst_object, |
400 |
headers=headers)
|
|
419 |
public, headers)
|
|
401 | 420 |
|
402 | 421 |
def move_object(self, src_container, src_object, dst_container, |
403 | 422 |
dst_object, headers=None): |
404 | 423 |
self._change_obj_location(src_container, src_object, |
405 |
dst_container, dst_object, True, headers) |
|
424 |
dst_container, dst_object, True, |
|
425 |
public, headers) |
|
406 | 426 |
|
407 | 427 |
def delete_object(self, container, object): |
408 | 428 |
self.delete('/%s/%s' % (container, object)) |
... | ... | |
437 | 457 |
actualy removes trash object metadata info |
438 | 458 |
""" |
439 | 459 |
self.delete_object_metadata(container, object, ['trash']) |
440 |
|
|
460 |
|
|
461 |
def publish_object(self, container, object): |
|
462 |
""" |
|
463 |
sets a previously created object publicly accessible |
|
464 |
""" |
|
465 |
path = '/%s/%s' % (container, object) |
|
466 |
headers = {} |
|
467 |
headers['Content-Range'] = 'bytes */*' |
|
468 |
self._set_public(headers, public=True) |
|
469 |
self.post(path, headers=headers) |
|
470 |
|
|
471 |
def unpublish_object(self, container, object): |
|
472 |
""" |
|
473 |
unpublish an object |
|
474 |
""" |
|
475 |
path = '/%s/%s' % (container, object) |
|
476 |
headers = {} |
|
477 |
headers['Content-Range'] = 'bytes */*' |
|
478 |
self._set_public(headers, public=False) |
|
479 |
self.post(path, headers=headers) |
b/tools/store | ||
---|---|---|
315 | 315 |
@cli_command('put') |
316 | 316 |
class PutObject(Command): |
317 | 317 |
syntax = '<container>/<object> <path> [key=val] [...]' |
318 |
description = 'create/override object with path contents or standard input'
|
|
318 |
description = 'create/override object' |
|
319 | 319 |
|
320 | 320 |
def add_options(self, parser): |
321 | 321 |
parser.add_option('--use_hashes', action='store_true', dest='use_hashes', |
... | ... | |
339 | 339 |
parser.add_option('--type', action='store', |
340 | 340 |
dest='content-type', default=False, |
341 | 341 |
help='create object with specific content type') |
342 |
#parser.add_option('--touch', action='store_true', |
|
343 |
# dest='touch', default=False, |
|
344 |
# help='create object with zero data') |
|
345 | 342 |
parser.add_option('--sharing', action='store', |
346 | 343 |
dest='sharing', default=None, |
347 | 344 |
help='define sharing object policy') |
348 | 345 |
parser.add_option('-f', action='store', |
349 | 346 |
dest='srcpath', default=None, |
350 |
help='file descriptor to read from: pass - for standard input') |
|
351 |
|
|
347 |
help='file descriptor to read from (pass - for standard input)') |
|
348 |
parser.add_option('--public', action='store', |
|
349 |
dest='public', default=None, |
|
350 |
help='make object publicly accessible (\'True\'/\'False\')') |
|
351 |
|
|
352 | 352 |
def execute(self, path, *args): |
353 | 353 |
if path.find('=') != -1: |
354 | 354 |
raise Fault('Missing path argument') |
... | ... | |
383 | 383 |
|
384 | 384 |
if self.use_hashes and not f: |
385 | 385 |
raise Fault('Illegal option combination') |
386 |
|
|
386 |
if self.public not in ['True', 'False', None]: |
|
387 |
raise Fault('Not acceptable value for public') |
|
388 |
public = eval(self.public) if self.public else None |
|
387 | 389 |
self.client.create_object(container, object, f, chunked=self.chunked, |
388 | 390 |
headers=headers, use_hashes=self.use_hashes, |
389 |
**meta) |
|
391 |
public=public, **meta)
|
|
390 | 392 |
if f: |
391 | 393 |
f.close() |
392 | 394 |
|
393 | 395 |
@cli_command('copy', 'cp') |
394 | 396 |
class CopyObject(Command): |
395 | 397 |
syntax = '<src container>/<src object> [<dst container>/]<dst object>' |
396 |
description = 'copies an object to a different location'
|
|
398 |
description = 'copy an object to a different location'
|
|
397 | 399 |
|
398 | 400 |
def add_options(self, parser): |
399 | 401 |
parser.add_option('--version', action='store', |
400 | 402 |
dest='version', default=False, |
401 | 403 |
help='copy specific version') |
404 |
parser.add_option('--public', action='store', |
|
405 |
dest='public', default=None, |
|
406 |
help='publish/unpublish object (\'True\'/\'False\')') |
|
402 | 407 |
|
403 | 408 |
def execute(self, src, dst): |
404 | 409 |
src_container, sep, src_object = src.partition('/') |
... | ... | |
410 | 415 |
if version: |
411 | 416 |
headers = {} |
412 | 417 |
headers['X_SOURCE_VERSION'] = version |
418 |
if self.public and self.nopublic: |
|
419 |
raise Fault('Conflicting options') |
|
420 |
if self.public not in ['True', 'False', None]: |
|
421 |
raise Fault('Not acceptable value for public') |
|
422 |
public = eval(self.public) if self.public else None |
|
413 | 423 |
self.client.copy_object(src_container, src_object, dst_container, |
414 |
dst_object, headers) |
|
424 |
dst_object, public, headers)
|
|
415 | 425 |
|
416 | 426 |
@cli_command('set') |
417 | 427 |
class SetMeta(Command): |
... | ... | |
470 | 480 |
parser.add_option('-f', action='store', |
471 | 481 |
dest='srcpath', default=None, |
472 | 482 |
help='file descriptor to read from: pass - for standard input') |
483 |
parser.add_option('--public', action='store', |
|
484 |
dest='public', default=None, |
|
485 |
help='publish/unpublish object (\'True\'/\'False\')') |
|
473 | 486 |
|
474 | 487 |
def execute(self, path, *args): |
475 | 488 |
if path.find('=') != -1: |
... | ... | |
503 | 516 |
f = self.srcpath != '-' and open(self.srcpath) or stdin |
504 | 517 |
if f: |
505 | 518 |
chunked = True if (self.chunked or f == stdin) else False |
519 |
if self.public not in ['True', 'False', None]: |
|
520 |
raise Fault('Not acceptable value for public') |
|
521 |
public = eval(self.public) if self.public else None |
|
506 | 522 |
self.client.update_object(container, object, f, chunked=chunked, |
507 |
headers=headers, offset=self.offset, **meta) |
|
523 |
headers=headers, offset=self.offset, |
|
524 |
public=public, **meta) |
|
508 | 525 |
if f: |
509 | 526 |
f.close() |
510 | 527 |
|
511 | 528 |
@cli_command('move', 'mv') |
512 | 529 |
class MoveObject(Command): |
513 | 530 |
syntax = '<src container>/<src object> [<dst container>/]<dst object>' |
514 |
description = 'moves an object to a different location' |
|
531 |
description = 'move an object to a different location' |
|
532 |
|
|
533 |
def add_options(self, parser): |
|
534 |
parser.add_option('--public', action='store', |
|
535 |
dest='public', default=None, |
|
536 |
help='publish/unpublish object (\'True\'/\'False\')') |
|
515 | 537 |
|
516 | 538 |
def execute(self, src, dst): |
517 | 539 |
src_container, sep, src_object = src.partition('/') |
... | ... | |
519 | 541 |
if not sep: |
520 | 542 |
dst_container = src_container |
521 | 543 |
dst_object = dst |
522 |
|
|
544 |
if self.public not in ['True', 'False', None]: |
|
545 |
raise Fault('Not acceptable value for public') |
|
546 |
public = eval(self.public) if self.public else None |
|
523 | 547 |
self.client.move_object(src_container, src_object, dst_container, |
524 |
dst_object, headers) |
|
548 |
dst_object, public, headers)
|
|
525 | 549 |
|
526 | 550 |
@cli_command('remove') |
527 | 551 |
class TrashObject(Command): |
528 | 552 |
syntax = '<container>/<object>' |
529 |
description = 'trashes an object'
|
|
553 |
description = 'trash an object' |
|
530 | 554 |
|
531 | 555 |
def execute(self, src): |
532 | 556 |
src_container, sep, src_object = src.partition('/') |
... | ... | |
534 | 558 |
self.client.trash_object(src_container, src_object) |
535 | 559 |
|
536 | 560 |
@cli_command('restore') |
537 |
class TrashObject(Command):
|
|
561 |
class RestoreObject(Command):
|
|
538 | 562 |
syntax = '<container>/<object>' |
539 |
description = 'trashes an object'
|
|
563 |
description = 'restore a trashed object'
|
|
540 | 564 |
|
541 | 565 |
def execute(self, src): |
542 | 566 |
src_container, sep, src_object = src.partition('/') |
... | ... | |
546 | 570 |
@cli_command('unset') |
547 | 571 |
class UnsetObject(Command): |
548 | 572 |
syntax = '<container>/[<object>] key [key] [...]' |
549 |
description = 'deletes metadata info'
|
|
573 |
description = 'delete metadata info' |
|
550 | 574 |
|
551 | 575 |
def execute(self, path, *args): |
552 | 576 |
#in case of account fix the args |
... | ... | |
581 | 605 |
@cli_command('policy') |
582 | 606 |
class SetPolicy(Command): |
583 | 607 |
syntax = 'container key=val [key=val] [...]' |
584 |
description = 'set contianer policies'
|
|
608 |
description = 'set container policies'
|
|
585 | 609 |
|
586 | 610 |
def execute(self, path, *args): |
587 | 611 |
if path.find('=') != -1: |
... | ... | |
599 | 623 |
|
600 | 624 |
self.client.set_container_policies(container, **policies) |
601 | 625 |
|
626 |
@cli_command('publish') |
|
627 |
class PublishObject(Command): |
|
628 |
syntax = '<container>/<object>' |
|
629 |
description = 'publish an object' |
|
630 |
|
|
631 |
def execute(self, src): |
|
632 |
src_container, sep, src_object = src.partition('/') |
|
633 |
|
|
634 |
self.client.publish_object(src_container, src_object) |
|
635 |
|
|
636 |
@cli_command('unpublish') |
|
637 |
class UnpublishObject(Command): |
|
638 |
syntax = '<container>/<object>' |
|
639 |
description = 'unpublish an object' |
|
640 |
|
|
641 |
def execute(self, src): |
|
642 |
src_container, sep, src_object = src.partition('/') |
|
643 |
|
|
644 |
self.client.unpublish_object(src_container, src_object) |
|
645 |
|
|
602 | 646 |
def print_usage(): |
603 | 647 |
cmd = Command('', []) |
604 | 648 |
parser = cmd.parser |
Also available in: Unified diff