Revision 761e0cbf
b/kamaki/cli/commands/pithos_cli.py | ||
---|---|---|
526 | 526 |
self._run() |
527 | 527 |
|
528 | 528 |
|
529 |
@command(pithos_cmds) |
|
530 |
class store_copy(_store_container_command): |
|
531 |
"""Copy objects from container to (another) container |
|
532 |
Semantics: |
|
533 |
copy cont:path dir |
|
534 |
. transfer path as dir/path |
|
535 |
copy cont:path cont2: |
|
536 |
. trasnfer all <obj> prefixed with path to container cont2 |
|
537 |
copy cont:path [cont2:]path2 |
|
538 |
. transfer path to path2 |
|
539 |
Use options: |
|
540 |
1. <container1>:<path1> [container2:]<path2> : if container2 is not given, |
|
541 |
destination is container1:path2 |
|
542 |
2. <container>:<path1> <path2> : make a copy in the same container |
|
543 |
3. Can use --container= instead of <container1> |
|
544 |
""" |
|
529 |
class _source_destination_command(_store_container_command): |
|
545 | 530 |
|
546 | 531 |
arguments = dict( |
547 |
destination_container=ValueArgument( |
|
548 |
'use it if destination container name contains a : character', |
|
549 |
'--dst-container'), |
|
550 |
source_version=ValueArgument( |
|
551 |
'copy specific version', |
|
552 |
'--source-version'), |
|
553 |
public=ValueArgument('make object publicly accessible', '--public'), |
|
554 |
content_type=ValueArgument( |
|
555 |
'change object\'s content type', |
|
556 |
'--content-type'), |
|
557 |
recursive=FlagArgument( |
|
558 |
'copy directory and contents', |
|
559 |
('-r', '--recursive')), |
|
560 |
prefix=FlagArgument( |
|
561 |
'Match objects prefixed with src path (feels like src_path*)', |
|
562 |
'--with-prefix', |
|
563 |
default=''), |
|
564 |
suffix=ValueArgument( |
|
565 |
'Suffix of source objects (feels like *suffix)', |
|
566 |
'--with-suffix', |
|
567 |
default=''), |
|
568 |
add_prefix=ValueArgument('Prefix targets', '--add-prefix', default=''), |
|
569 |
add_suffix=ValueArgument('Suffix targets', '--add-suffix', default=''), |
|
570 |
prefix_replace=ValueArgument( |
|
571 |
'Prefix of src to replace with dst path + add_prefix, if matched', |
|
572 |
'--prefix-to-replace', |
|
573 |
default=''), |
|
574 |
suffix_replace=ValueArgument( |
|
575 |
'Suffix of src to replace with add_suffix, if matched', |
|
576 |
'--suffix-to-replace', |
|
577 |
default='') |
|
532 |
recursive=FlagArgument('', ('-r', '--recursive')), |
|
533 |
prefix=FlagArgument('', '--with-prefix', default=''), |
|
534 |
suffix=ValueArgument('', '--with-suffix', default=''), |
|
535 |
add_prefix=ValueArgument('', '--add-prefix', default=''), |
|
536 |
add_suffix=ValueArgument('', '--add-suffix', default=''), |
|
537 |
prefix_replace=ValueArgument('', '--prefix-to-replace', default=''), |
|
538 |
suffix_replace=ValueArgument('', '--suffix-to-replace', default='') |
|
578 | 539 |
) |
579 | 540 |
|
541 |
def __init__(self, arguments={}): |
|
542 |
self.arguments.update(arguments) |
|
543 |
super(_source_destination_command, self).__init__(self.arguments) |
|
544 |
|
|
580 | 545 |
def _get_all(self, prefix): |
581 | 546 |
return self.client.container_get(prefix=prefix).json |
582 | 547 |
|
... | ... | |
615 | 580 |
srcobj['name'] = src_path |
616 | 581 |
return srcobj |
617 | 582 |
|
618 |
def _objlist(self, dst_cont, dst_path):
|
|
583 |
def src_dst_pairs(self, dst_cont, dst_path):
|
|
619 | 584 |
src_iter = self._get_src_objects(self.container, self.path) |
620 | 585 |
src_N = isinstance(src_iter, tuple) |
621 | 586 |
add_prefix = self['add_prefix'].strip('/') |
... | ... | |
670 | 635 |
obj = obj[:-len(self['suffix_replace'])] |
671 | 636 |
return add_prefix + obj + self['add_suffix'] |
672 | 637 |
|
638 |
|
|
639 |
@command(pithos_cmds) |
|
640 |
class store_copy(_source_destination_command): |
|
641 |
"""Copy objects from container to (another) container |
|
642 |
Semantics: |
|
643 |
copy cont:path dir |
|
644 |
. transfer path as dir/path |
|
645 |
copy cont:path cont2: |
|
646 |
. trasnfer all <obj> prefixed with path to container cont2 |
|
647 |
copy cont:path [cont2:]path2 |
|
648 |
. transfer path to path2 |
|
649 |
Use options: |
|
650 |
1. <container1>:<path1> [container2:]<path2> : if container2 is not given, |
|
651 |
destination is container1:path2 |
|
652 |
2. <container>:<path1> <path2> : make a copy in the same container |
|
653 |
3. Can use --container= instead of <container1> |
|
654 |
""" |
|
655 |
|
|
656 |
arguments = dict( |
|
657 |
destination_container=ValueArgument( |
|
658 |
'use it if destination container name contains a : character', |
|
659 |
'--dst-container'), |
|
660 |
source_version=ValueArgument( |
|
661 |
'copy specific version', |
|
662 |
'--source-version'), |
|
663 |
public=ValueArgument('make object publicly accessible', '--public'), |
|
664 |
content_type=ValueArgument( |
|
665 |
'change object\'s content type', |
|
666 |
'--content-type'), |
|
667 |
recursive=FlagArgument( |
|
668 |
'copy directory and contents', |
|
669 |
('-r', '--recursive')), |
|
670 |
prefix=FlagArgument( |
|
671 |
'Match objects prefixed with src path (feels like src_path*)', |
|
672 |
'--with-prefix', |
|
673 |
default=''), |
|
674 |
suffix=ValueArgument( |
|
675 |
'Suffix of source objects (feels like *suffix)', |
|
676 |
'--with-suffix', |
|
677 |
default=''), |
|
678 |
add_prefix=ValueArgument('Prefix targets', '--add-prefix', default=''), |
|
679 |
add_suffix=ValueArgument('Suffix targets', '--add-suffix', default=''), |
|
680 |
prefix_replace=ValueArgument( |
|
681 |
'Prefix of src to replace with dst path + add_prefix, if matched', |
|
682 |
'--prefix-to-replace', |
|
683 |
default=''), |
|
684 |
suffix_replace=ValueArgument( |
|
685 |
'Suffix of src to replace with add_suffix, if matched', |
|
686 |
'--suffix-to-replace', |
|
687 |
default='') |
|
688 |
) |
|
689 |
|
|
673 | 690 |
@errors.generic.all |
674 | 691 |
@errors.pithos.connection |
675 | 692 |
@errors.pithos.container |
676 | 693 |
def _run(self, dst_cont, dst_path): |
677 | 694 |
no_source_object = True |
678 |
for src_object, dst_object in self._objlist(dst_cont, dst_path):
|
|
695 |
for src_object, dst_object in self.src_dst_pairs(dst_cont, dst_path):
|
|
679 | 696 |
no_source_object = False |
680 | 697 |
self.client.copy_object( |
681 | 698 |
src_container=self.container, |
... | ... | |
703 | 720 |
|
704 | 721 |
|
705 | 722 |
@command(pithos_cmds) |
706 |
class store_move(_store_container_command):
|
|
707 |
"""Move/rename objects |
|
723 |
class store_move(_source_destination_command):
|
|
724 |
"""Move/rename objects from container to (another) container
|
|
708 | 725 |
Semantics: |
709 |
move cont:path path2 |
|
710 |
. will move all <obj> prefixed with path, as path2<obj> |
|
711 |
. or as path2 if path corresponds to just one whole object |
|
726 |
move cont:path dir |
|
727 |
. rename path as dir/path |
|
712 | 728 |
move cont:path cont2: |
713 |
. will move all <obj> prefixed with path to container cont2 |
|
714 |
move cont:path [cont2:]path2 --exact-match |
|
715 |
. will move at most one <obj> as a new object named path2, |
|
716 |
. provided path corresponds to a whole object path |
|
717 |
move cont:path [cont2:]path2 --replace |
|
718 |
. will move all <obj> prefixed with path, replacing path with path2 |
|
719 |
where <obj> is a full file or directory object path. |
|
729 |
. trasnfer all <obj> prefixed with path to container cont2 |
|
730 |
move cont:path [cont2:]path2 |
|
731 |
. transfer path to path2 |
|
720 | 732 |
Use options: |
721 |
1. <container1>:<path1> [container2:]<path2> : if container2 not given, |
|
733 |
1. <container1>:<path1> [container2:]<path2> : if container2 is not given,
|
|
722 | 734 |
destination is container1:path2 |
723 |
2. <container>:<path1> path2 : rename
|
|
735 |
2. <container>:<path1> <path2> : move in the same container
|
|
724 | 736 |
3. Can use --container= instead of <container1> |
725 | 737 |
""" |
726 | 738 |
|
... | ... | |
728 | 740 |
destination_container=ValueArgument( |
729 | 741 |
'use it if destination container name contains a : character', |
730 | 742 |
'--dst-container'), |
731 |
source_version=ValueArgument('specify version', '--source-version'), |
|
732 |
public=FlagArgument('make object publicly accessible', '--public'), |
|
733 |
content_type=ValueArgument('modify content type', '--content-type'), |
|
734 |
recursive=FlagArgument('up to delimiter /', ('-r', '--recursive')), |
|
735 |
exact_match=FlagArgument( |
|
736 |
'Copy only the object that fully matches path', |
|
737 |
'--exact-match'), |
|
738 |
replace=FlagArgument('Replace src. path with dst. path', '--replace') |
|
743 |
source_version=ValueArgument( |
|
744 |
'copy specific version', |
|
745 |
'--source-version'), |
|
746 |
public=ValueArgument('make object publicly accessible', '--public'), |
|
747 |
content_type=ValueArgument( |
|
748 |
'change object\'s content type', |
|
749 |
'--content-type'), |
|
750 |
recursive=FlagArgument( |
|
751 |
'copy directory and contents', |
|
752 |
('-r', '--recursive')), |
|
753 |
prefix=FlagArgument( |
|
754 |
'Match objects prefixed with src path (feels like src_path*)', |
|
755 |
'--with-prefix', |
|
756 |
default=''), |
|
757 |
suffix=ValueArgument( |
|
758 |
'Suffix of source objects (feels like *suffix)', |
|
759 |
'--with-suffix', |
|
760 |
default=''), |
|
761 |
add_prefix=ValueArgument('Prefix targets', '--add-prefix', default=''), |
|
762 |
add_suffix=ValueArgument('Suffix targets', '--add-suffix', default=''), |
|
763 |
prefix_replace=ValueArgument( |
|
764 |
'Prefix of src to replace with dst path + add_prefix, if matched', |
|
765 |
'--prefix-to-replace', |
|
766 |
default=''), |
|
767 |
suffix_replace=ValueArgument( |
|
768 |
'Suffix of src to replace with add_suffix, if matched', |
|
769 |
'--suffix-to-replace', |
|
770 |
default='') |
|
739 | 771 |
) |
740 | 772 |
|
741 |
def _objlist(self, dst_path): |
|
742 |
if self['exact_match']: |
|
743 |
return [(dst_path or self.path, self.path)] |
|
744 |
r = self.client.container_get(prefix=self.path) |
|
745 |
if len(r.json) == 1: |
|
746 |
obj = r.json[0] |
|
747 |
return [(obj['name'], dst_path or obj['name'])] |
|
748 |
return [( |
|
749 |
obj['name'], |
|
750 |
'%s%s' % ( |
|
751 |
dst_path, |
|
752 |
obj['name'][len(self.path) if self['replace'] else 0:] |
|
753 |
)) for obj in r.json] |
|
754 |
|
|
755 | 773 |
@errors.generic.all |
756 | 774 |
@errors.pithos.connection |
757 | 775 |
@errors.pithos.container |
758 | 776 |
def _run(self, dst_cont, dst_path): |
759 | 777 |
no_source_object = True |
760 |
for src_object, dst_object in self._objlist(dst_path):
|
|
778 |
for src_object, dst_object in self.src_dst_pairs(dst_cont, dst_path):
|
|
761 | 779 |
no_source_object = False |
762 | 780 |
self.client.move_object( |
763 | 781 |
src_container=self.container, |
764 | 782 |
src_object=src_object, |
765 |
dst_container=dst_cont or self.container,
|
|
783 |
dst_container=dst_cont, |
|
766 | 784 |
dst_object=dst_object, |
767 | 785 |
source_version=self['source_version'], |
768 | 786 |
public=self['public'], |
... | ... | |
779 | 797 |
super(self.__class__, self)._run( |
780 | 798 |
source_container___path, |
781 | 799 |
path_is_optional=False) |
782 |
(dst_cont, dst_path) = self._dest_container_path(
|
|
800 |
(dst_cnt, dst_path) = self._dest_container_path( |
|
783 | 801 |
destination_container___path) |
784 |
self._run(dst_cont=dst_cont, dst_path=dst_path or '')
|
|
802 |
self._run(dst_cont=dst_cnt or self.container, dst_path=dst_path or '')
|
|
785 | 803 |
|
786 | 804 |
|
787 | 805 |
@command(pithos_cmds) |
Also available in: Unified diff