diff --git a/app-openbis-command-line/src/python/obis/dm/commands/download_physical.py b/app-openbis-command-line/src/python/obis/dm/commands/download_physical.py index 4d12d11f838c49923383f9ddd95566abe8cbe24c..44845cf12abe87dfa2f7e1823c0424cc679cc1c2 100644 --- a/app-openbis-command-line/src/python/obis/dm/commands/download_physical.py +++ b/app-openbis-command-line/src/python/obis/dm/commands/download_physical.py @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import os from .openbis_command import OpenbisCommand +from ..checksum import validate_checksum from ..command_result import CommandResult from ..utils import cd +from ...scripts.click_util import click_echo class DownloadPhysical(OpenbisCommand): @@ -23,13 +26,14 @@ class DownloadPhysical(OpenbisCommand): Command to download physical files of a data set. """ - def __init__(self, dm, data_set_id, file): + def __init__(self, dm, data_set_id, file, skip_integrity_check): """ :param dm: data management :param data_set_id: permId of the data set to be cloned """ self.data_set_id = data_set_id self.files = [file] if file is not None else None + self.skip_integrity_check = skip_integrity_check self.load_global_config(dm) super(DownloadPhysical, self).__init__(dm) @@ -43,4 +47,25 @@ class DownloadPhysical(OpenbisCommand): with cd(self.data_mgmt.invocation_path): target_folder = data_set.download(files, destination=self.data_mgmt.invocation_path) + if self.skip_integrity_check is not True: + invalid_files = validate_checksum(self.openbis, files, data_set.permId, + target_folder, None) + self.redownload_invalid_files_on_demand(invalid_files, target_folder) return CommandResult(returncode=0, output="Files downloaded to: %s" % target_folder) + + def redownload_invalid_files_on_demand(self, invalid_files, target_folder): + if len(invalid_files) == 0: + return + yes_or_no = None + while yes_or_no != "yes" and yes_or_no != "no": + click_echo("Integrity check failed for following files:\n" + + str(invalid_files) + "\n" + + "Either the download failed or the files where changed after committing to openBIS.\n" + + "Should the files be downloaded again? (yes/no)") + yes_or_no = input('> ') + if yes_or_no == "yes": + for file in invalid_files: + filename_dest = os.path.join(target_folder, file) + os.remove(filename_dest) + self.files = invalid_files + return self.run() diff --git a/app-openbis-command-line/src/python/obis/dm/data_mgmt.py b/app-openbis-command-line/src/python/obis/dm/data_mgmt.py index 96e5e902c970764a97ffd010c3525a5ec9048c44..15d9b5cdf251815f7ea5c1177ae4f765913e3e4d 100644 --- a/app-openbis-command-line/src/python/obis/dm/data_mgmt.py +++ b/app-openbis-command-line/src/python/obis/dm/data_mgmt.py @@ -210,10 +210,9 @@ class AbstractDataMgmt(metaclass=abc.ABCMeta): return @abc.abstractmethod - def download(self, data_set_id, content_copy_index, file, skip_integrity_check): + def download(self, data_set_id, file, skip_integrity_check): """Download files of a repository without adding a content copy. :param data_set_id: Id of the data set to download from. - :param content_copy_index: Index of the content copy to download from. :param file: Path of a file in the data set to download. All files are downloaded if it is None. :param skip_integrity_check: Checksums of files are not verified if true. """ @@ -350,7 +349,7 @@ class NoGitDataMgmt(AbstractDataMgmt): def removeref(self, data_set_id=None): self.error_raise("removeref", "No git command found.") - def download(self, data_set_id, content_copy_index, file, skip_integrity_check): + def download(self, data_set_id, file, skip_integrity_check): self.error_raise("download", "No git command found.") def search_object(self, *_): @@ -560,7 +559,7 @@ class GitDataMgmt(AbstractDataMgmt): cmd = Removeref(self, data_set_id=data_set_id) return cmd.run() - def download(self, data_set_id, content_copy_index, file, skip_integrity_check): + def download(self, data_set_id, file, skip_integrity_check): self.error_raise("download", "This command is only available for Manager Data.") # @@ -646,8 +645,8 @@ class PhysicalDataMgmt(AbstractDataMgmt): def removeref(self, data_set_id=None): self.error_raise("removeref", "This command is only available for External Manager Data") - def download(self, data_set_id, _content_copy_index, file, _skip_integrity_check): - cmd = DownloadPhysical(self, data_set_id, file) + def download(self, data_set_id, file, skip_integrity_check): + cmd = DownloadPhysical(self, data_set_id, file, skip_integrity_check) return cmd.run() def upload(self, sample_id, data_set_type, files): diff --git a/app-openbis-command-line/src/python/obis/scripts/cli.py b/app-openbis-command-line/src/python/obis/scripts/cli.py index 175356088c911ee97f1a3042fc5bb133a5537c58..be6804e1cc66ecd2c56b5690f95a31fceeb4f1a8 100644 --- a/app-openbis-command-line/src/python/obis/scripts/cli.py +++ b/app-openbis-command-line/src/python/obis/scripts/cli.py @@ -270,7 +270,8 @@ def repository_clear(ctx, settings): _search_params = [ - click.option('-type', '--type', 'type_code', default=None, help='Type code to filter by'), + click.option('-object_type', '--object_type', 'type_code', default=None, + help='Object type code to filter by'), click.option('-space', '--space', default=None, help='Space code'), click.option('-project', '--project', default=None, help='Full project identification code'), click.option('-experiment', '--experiment', default=None, help='Full experiment code'), @@ -757,31 +758,29 @@ def removeref(ctx, data_set_id, repository): # download _download_params = [ - click.option('-c', '--content_copy_index', type=int, default=None, - help='Index of the content copy to download from.'), + click.argument('data_set_id'), click.option( '-f', '--file', help='File in the data set to download - downloading all if not given.'), - click.option('-s', '--skip_integrity_check', default=False, - is_flag=True, help='Skip file integrity check with checksums.'), - click.argument('data_set_id'), + click.option('-s', '--skip_integrity_check', default=False, is_flag=True, + help='Flag to skip file integrity check with checksums'), ] @data_set.command("download", short_help="Download files of a data set.") @add_params(_download_params) @click.pass_context -def data_set_download(ctx, content_copy_index, file, data_set_id, skip_integrity_check): +def data_set_download(ctx, file, data_set_id, skip_integrity_check): return ctx.obj['runner'].run("download", - lambda dm: dm.download(data_set_id, content_copy_index, file, - skip_integrity_check)) + lambda dm: dm.download(data_set_id=data_set_id, file=file, + skip_integrity_check=skip_integrity_check)) @cli.command("download", short_help="Download files of a data set.") @add_params(_download_params) @click.pass_context -def download(ctx, content_copy_index, file, data_set_id, skip_integrity_check): +def download(ctx, file, data_set_id, skip_integrity_check): ctx.obj['runner'] = DataMgmtRunner(ctx.obj, halt_on_error_log=False) - ctx.invoke(data_set_download, content_copy_index=content_copy_index, file=file, + ctx.invoke(data_set_download, file=file, data_set_id=data_set_id, skip_integrity_check=skip_integrity_check) diff --git a/docs/app-openbis-command-line/README.md b/docs/app-openbis-command-line/README.md index 7a3ffc8f360881c562d4ff0a76dbac7024886222..62505db94e28bfce7854a9bac0370995cae98986 100644 --- a/docs/app-openbis-command-line/README.md +++ b/docs/app-openbis-command-line/README.md @@ -199,7 +199,8 @@ it comes to integration with other tools. obis data_set search [OPTIONS] Options: - -type, --type TEXT Type code to filter by + -object_type, --object_type TEXT + Object type code to filter by -space, --space TEXT Space code -project, --project TEXT Full project identification code -experiment, --experiment TEXT Full experiment code