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