add -r recursive option for ls command.

This commit is contained in:
Yoshihiro OKUMURA 2023-06-06 19:59:55 +09:00
parent da57fc7c6c
commit 3982521530
Signed by: orrisroot
GPG Key ID: 470AA444C92904B2

View File

@ -1,6 +1,27 @@
from argparse import Namespace, _SubParsersAction from argparse import Namespace, _SubParsersAction
from pydantic.dataclasses import dataclass
from mdrsclient.api import FolderApi
from mdrsclient.commands.base import BaseCommand 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): class LsCommand(BaseCommand):
@ -9,6 +30,13 @@ class LsCommand(BaseCommand):
command = cls() command = cls()
ls_parser = parsers.add_parser("ls", help="list the folder contents") 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("-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.add_argument("remote_path", help="remote folder path (remote:/lab/path/)")
ls_parser.set_defaults(func=command.ls) 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) (remote, laboratory_name, r_path) = self._parse_remote_host_with_path(args.remote_path)
connection = self._create_connection(remote) connection = self._create_connection(remote)
laboratory = self._find_laboratory(connection, laboratory_name) 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 = { label = {
"type": "Type", "type": "Type",
"acl": "Access", "acl": "Access",
@ -27,9 +69,9 @@ class LsCommand(BaseCommand):
} }
length: dict[str, int] = {} length: dict[str, int] = {}
for key in label.keys(): 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: 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)" 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["acl"] = max(length["acl"], len(sub_folder.access_level_name))
length["laboratory"] = max(length["laboratory"], len(sub_laboratory_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["date"] = max(length["date"], len(file.updated_at_name))
length["name"] = max(length["name"], len(file.name)) length["name"] = max(length["name"], len(file.name))
length["acl"] = max(length["acl"], len(folder.access_level_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 = ( header = (
f"{label['type']:{length['type']}}\t{label['acl']:{length['acl']}}\t" f"{label['type']:{length['type']}}\t{label['acl']:{length['acl']}}\t"
f"{label['laboratory']:{length['laboratory']}}\t{label['size']:{length['size']}}\t" f"{label['laboratory']:{length['laboratory']}}\t{label['size']:{length['size']}}\t"
f"{label['date']:{length['date']}}\t{label['name']:{length['name']}}" 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): 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)" sub_laboratory_name = sub_laboratory.name if sub_laboratory is not None else "(invalid)"
print( print(
f"{'[d]':{length['type']}}\t{sub_folder.access_level_name:{length['acl']}}\t" 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): for file in sorted(folder.files, key=lambda x: x.name):
print( print(
f"{'[f]':{length['type']}}\t{folder.access_level_name:{length['acl']}}\t" 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']}}" 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