From 3982521530a79eb4c5713654edbeb215f96496cc Mon Sep 17 00:00:00 2001 From: Yoshihiro OKUMURA Date: Tue, 6 Jun 2023 19:59:55 +0900 Subject: [PATCH] add -r recursive option for `ls` command. --- mdrsclient/commands/ls.py | 76 ++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/mdrsclient/commands/ls.py b/mdrsclient/commands/ls.py index e7d34f2..eb79561 100644 --- a/mdrsclient/commands/ls.py +++ b/mdrsclient/commands/ls.py @@ -1,6 +1,27 @@ from argparse import Namespace, _SubParsersAction +from pydantic.dataclasses import dataclass + +from mdrsclient.api import FolderApi from mdrsclient.commands.base import BaseCommand +from mdrsclient.connection import MDRSConnection +from mdrsclient.exceptions import UnauthorizedException +from mdrsclient.models import Folder, Laboratory + + +class Config: + arbitrary_types_allowed = True + frozen = True + + +@dataclass(config=Config) +class LsCommandContext: + prefix: str + connection: MDRSConnection + laboratory: Laboratory + password: str + is_quick: bool + is_recursive: bool class LsCommand(BaseCommand): @@ -9,6 +30,13 @@ class LsCommand(BaseCommand): command = cls() ls_parser = parsers.add_parser("ls", help="list the folder contents") ls_parser.add_argument("-p", "--password", help="password to use when open locked folder") + ls_parser.add_argument( + "-q", + "--quick", + help="don't output header row. this option is forced if the -r option is specified", + action="store_true", + ) + ls_parser.add_argument("-r", "--recursive", help="list the folders contents recursive", action="store_true") ls_parser.add_argument("remote_path", help="remote folder path (remote:/lab/path/)") ls_parser.set_defaults(func=command.ls) @@ -16,7 +44,21 @@ class LsCommand(BaseCommand): (remote, laboratory_name, r_path) = self._parse_remote_host_with_path(args.remote_path) connection = self._create_connection(remote) laboratory = self._find_laboratory(connection, laboratory_name) - folder = self._find_folder(connection, laboratory, r_path, args.password) + password = str(args.password) + is_recursive = bool(args.recursive) + is_quick = bool(args.quick) if not is_recursive else True + self.context = LsCommandContext( + f"{remote}:/{laboratory_name}", + connection, + laboratory, + password, + is_quick, + is_recursive, + ) + folder = self._find_folder(connection, laboratory, r_path, password) + self._ls_body(folder) + + def _ls_body(self, folder: Folder) -> None: label = { "type": "Type", "acl": "Access", @@ -27,9 +69,9 @@ class LsCommand(BaseCommand): } length: dict[str, int] = {} for key in label.keys(): - length[key] = len(label[key]) + length[key] = len(label[key]) if not self.context.is_quick else 0 for sub_folder in folder.sub_folders: - sub_laboratory = connection.laboratories.find_by_id(sub_folder.lab_id) + sub_laboratory = self.context.connection.laboratories.find_by_id(sub_folder.lab_id) sub_laboratory_name = sub_laboratory.name if sub_laboratory is not None else "(invalid)" length["acl"] = max(length["acl"], len(sub_folder.access_level_name)) length["laboratory"] = max(length["laboratory"], len(sub_laboratory_name)) @@ -41,17 +83,23 @@ class LsCommand(BaseCommand): length["date"] = max(length["date"], len(file.updated_at_name)) length["name"] = max(length["name"], len(file.name)) length["acl"] = max(length["acl"], len(folder.access_level_name)) - length["laboratory"] = max(length["laboratory"], len(laboratory.name)) + length["laboratory"] = max(length["laboratory"], len(self.context.laboratory.name)) header = ( f"{label['type']:{length['type']}}\t{label['acl']:{length['acl']}}\t" f"{label['laboratory']:{length['laboratory']}}\t{label['size']:{length['size']}}\t" f"{label['date']:{length['date']}}\t{label['name']:{length['name']}}" ) - print(header) - print("-" * len(header.expandtabs())) + + if self.context.is_recursive: + print(f"{self.context.prefix}{folder.path}:") + print(f"total {sum(f.size for f in folder.files)}") + + if not self.context.is_quick: + print(header) + print("-" * len(header.expandtabs())) for sub_folder in sorted(folder.sub_folders, key=lambda x: x.name): - sub_laboratory = connection.laboratories.find_by_id(sub_folder.lab_id) + sub_laboratory = self.context.connection.laboratories.find_by_id(sub_folder.lab_id) sub_laboratory_name = sub_laboratory.name if sub_laboratory is not None else "(invalid)" print( f"{'[d]':{length['type']}}\t{sub_folder.access_level_name:{length['acl']}}\t" @@ -61,6 +109,18 @@ class LsCommand(BaseCommand): for file in sorted(folder.files, key=lambda x: x.name): print( f"{'[f]':{length['type']}}\t{folder.access_level_name:{length['acl']}}\t" - f"{laboratory.name:{length['laboratory']}}\t{file.size:{length['size']}}\t" + f"{self.context.laboratory.name:{length['laboratory']}}\t{file.size:{length['size']}}\t" f"{file.updated_at_name:{length['date']}}\t{file.name:{length['name']}}" ) + + if self.context.is_recursive: + print("") + for sub_folder in sorted(folder.sub_folders, key=lambda x: x.name): + folder_api = FolderApi(self.context.connection) + try: + if sub_folder.lock: + folder_api.auth(sub_folder.id, self.context.password) + folder = folder_api.retrieve(sub_folder.id) + self._ls_body(folder) + except UnauthorizedException: + pass