Revision ae99b37d
b/kamaki/cli/commands/pithos_cli.py | ||
---|---|---|
987 | 987 |
|
988 | 988 |
@command(pithos_cmds) |
989 | 989 |
class store_download(_store_container_command): |
990 |
"""Download remote object as local file""" |
|
990 |
"""Download remote object as local file |
|
991 |
If local destination is a directory: |
|
992 |
* download <container>:<path> <local dir> |
|
993 |
will download all files on <container> prefixed as <path>, |
|
994 |
to <local dir>/<full path> |
|
995 |
* download <container>:<path> <local dir> --exact-match |
|
996 |
will download only one file, exactly matching <path> |
|
997 |
""" |
|
991 | 998 |
|
992 | 999 |
arguments = dict( |
993 | 1000 |
resume=FlagArgument('Resume instead of overwrite', '--resume'), |
... | ... | |
1009 | 1016 |
progress_bar=ProgressBarArgument( |
1010 | 1017 |
'do not show progress bar', |
1011 | 1018 |
'--no-progress-bar', |
1012 |
default=False) |
|
1019 |
default=False), |
|
1020 |
exact_match=FlagArgument( |
|
1021 |
'Download only the object that matches path exactly', |
|
1022 |
'--exact-match') |
|
1013 | 1023 |
) |
1014 | 1024 |
|
1015 |
def _output_stream(self, local_path): |
|
1025 |
def _output_streams(self, local_path):
|
|
1016 | 1026 |
if local_path is None: |
1017 |
return stdout |
|
1018 |
return open( |
|
1019 |
path.abspath(local_path), 'rwb+' if self['resume'] else 'wb+') |
|
1027 |
return [(stdout, self.path)] |
|
1028 |
outpath = path.abspath(local_path) |
|
1029 |
wmode = 'rwb+' if self['resume'] else 'wb+' |
|
1030 |
try: |
|
1031 |
return [(open(outpath, wmode), self.path)] |
|
1032 |
except IOError as ioe: |
|
1033 |
if 'is a directory' in ('%s' % ioe).lower(): |
|
1034 |
if self['exact_match']: |
|
1035 |
return [( |
|
1036 |
open('%s/%s' % (outpath, self.path), wmode), |
|
1037 |
self.path |
|
1038 |
)] |
|
1039 |
remotes = self.client.container_get( |
|
1040 |
prefix=self.path, |
|
1041 |
if_modified_since=self['if_modified_since'], |
|
1042 |
if_unmodified_since=self['if_unmodified_since']) |
|
1043 |
return [( |
|
1044 |
open('%s/%s' % (outpath, remote['name']), wmode), |
|
1045 |
remote['name'] |
|
1046 |
) for remote in remotes.json] |
|
1047 |
raise |
|
1020 | 1048 |
|
1021 | 1049 |
@errors.generic.all |
1022 | 1050 |
@errors.pithos.connection |
... | ... | |
1024 | 1052 |
@errors.pithos.object_path |
1025 | 1053 |
@errors.pithos.local_path |
1026 | 1054 |
def _run(self, local_path): |
1027 |
out = self._output_stream(local_path)
|
|
1055 |
streams = self._output_streams(local_path)
|
|
1028 | 1056 |
poolsize = self['poolsize'] |
1029 | 1057 |
if poolsize: |
1030 | 1058 |
self.client.POOL_SIZE = int(poolsize) |
1031 |
try: |
|
1032 |
(progress_bar, download_cb) = self._safe_progress_bar( |
|
1033 |
'Downloading') |
|
1034 |
self.client.download_object( |
|
1059 |
if not streams: |
|
1060 |
raiseCLIError('No objects prefixed as %s on container %s' % ( |
|
1035 | 1061 |
self.path, |
1036 |
out, |
|
1037 |
download_cb=download_cb, |
|
1038 |
range=self['range'], |
|
1039 |
version=self['object_version'], |
|
1040 |
if_match=self['if_match'], |
|
1041 |
resume=self['resume'], |
|
1042 |
if_none_match=self['if_none_match'], |
|
1043 |
if_modified_since=self['if_modified_since'], |
|
1044 |
if_unmodified_since=self['if_unmodified_since']) |
|
1062 |
self.container)) |
|
1063 |
try: |
|
1064 |
for out, rpath in streams: |
|
1065 |
print('\nFrom %s:%s to %s/%s' % ( |
|
1066 |
self.container, |
|
1067 |
rpath, |
|
1068 |
local_path, |
|
1069 |
rpath)) |
|
1070 |
(progress_bar, |
|
1071 |
download_cb) = self._safe_progress_bar('Downloading') |
|
1072 |
self.client.download_object( |
|
1073 |
rpath, |
|
1074 |
out, |
|
1075 |
download_cb=download_cb, |
|
1076 |
range=self['range'], |
|
1077 |
version=self['object_version'], |
|
1078 |
if_match=self['if_match'], |
|
1079 |
resume=self['resume'], |
|
1080 |
if_none_match=self['if_none_match'], |
|
1081 |
if_modified_since=self['if_modified_since'], |
|
1082 |
if_unmodified_since=self['if_unmodified_since']) |
|
1045 | 1083 |
except KeyboardInterrupt: |
1046 | 1084 |
from threading import enumerate as activethreads |
1047 | 1085 |
stdout.write('\nFinishing active threads ') |
Also available in: Unified diff