11import sys
2+ from fnmatch import fnmatch
23from pathlib import Path
34from typing import List
45
56from prompt_toolkit .shortcuts import CompleteStyle
67from prompt_toolkit .validation import Validator , ValidationError
8+ from questionary import Choice
79
810from cirro .api .models .process import Process
911from cirro .api .models .project import Project
1012from cirro .cli .interactive .common_args import ask_project
11- from cirro .cli .interactive .utils import prompt_wrapper
13+ from cirro .cli .interactive .utils import ask
1214from cirro .cli .models import UploadArguments
13- from cirro .file_utils import get_directory_stats
15+ from cirro .file_utils import get_directory_stats , get_files_in_directory
1416
1517
1618class DataDirectoryValidator (Validator ):
@@ -23,82 +25,83 @@ def validate(self, document):
2325 )
2426
2527
26- def ask_data_directory (input_value : str ) -> str :
27- directory_prompt = {
28- 'type' : 'path' ,
29- 'name' : 'data_directory' ,
30- 'message' : 'Enter the full path of the data directory' ,
31- 'validate' : DataDirectoryValidator ,
32- 'default' : input_value or '' ,
33- 'complete_style' : CompleteStyle .READLINE_LIKE ,
34- 'only_directories' : True
35- }
28+ def confirm_data_directory (directory : str , files : List [str ]):
29+ stats = get_directory_stats (directory , files )
30+ is_accepted = ask (
31+ 'confirm' ,
32+ f'Please confirm that you wish to upload { stats ["numberOfFiles" ]} files ({ stats ["sizeFriendly" ]} )' ,
33+ default = True
34+ )
3635
37- answers = prompt_wrapper (directory_prompt )
38- return answers ['data_directory' ]
39-
40-
41- def confirm_data_directory (directory : str ):
42- stats = get_directory_stats (directory )
43- answers = prompt_wrapper ({
44- 'type' : 'confirm' ,
45- 'message' : f'Please confirm that you wish to upload { stats ["numberOfFiles" ]} files ({ stats ["sizeFriendly" ]} )' ,
46- 'name' : 'continue' ,
47- 'default' : True
48- })
49-
50- if not answers ['continue' ]:
36+ if not is_accepted :
5137 sys .exit (1 )
5238
5339
54- def ask_name (input_value : str ) -> str :
55- name_prompt = {
56- 'type' : 'input' ,
57- 'name' : 'name' ,
58- 'message' : 'What is the name of this dataset?' ,
59- 'validate' : lambda val : len (val .strip ()) > 0 or 'Please enter a name' ,
60- 'default' : input_value or ''
61- }
62-
63- answers = prompt_wrapper (name_prompt )
64- return answers ['name' ]
65-
66-
67- def ask_description (input_value : str ) -> str :
68- description_prompt = {
69- 'type' : 'input' ,
70- 'name' : 'description' ,
71- 'message' : 'Enter a description of the dataset (optional)' ,
72- 'default' : input_value or ''
73- }
74-
75- answers = prompt_wrapper (description_prompt )
76- return answers ['description' ]
77-
78-
7940def ask_process (processes : List [Process ], input_value : str ) -> str :
8041 process_names = [process .name for process in processes ]
81- process_prompt = {
82- 'type' : 'list' ,
83- 'name' : 'process' ,
84- 'message' : 'What type of files?' ,
85- 'choices' : process_names ,
86- 'default' : input_value if input_value in process_names else None
87- }
88- answers = prompt_wrapper (process_prompt )
89- return answers ['process' ]
42+ return ask (
43+ 'select' ,
44+ 'What type of files?' ,
45+ default = input_value if input_value in process_names else None ,
46+ choices = process_names
47+ )
9048
9149
9250def gather_upload_arguments (input_params : UploadArguments , projects : List [Project ], processes : List [Process ]):
9351 input_params ['project' ] = ask_project (projects , input_params .get ('project' ))
9452
95- input_params ['data_directory' ] = ask_data_directory (input_params .get ('data_directory' ))
96- confirm_data_directory (input_params ['data_directory' ])
53+ input_params ['data_directory' ] = ask (
54+ 'path' ,
55+ 'Enter the full path of the data directory' ,
56+ required = True ,
57+ validate = DataDirectoryValidator ,
58+ default = input_params .get ('data_directory' ) or '' ,
59+ complete_style = CompleteStyle .READLINE_LIKE ,
60+ only_directories = True
61+ )
62+
63+ upload_method = ask (
64+ 'select' ,
65+ 'What files would you like to upload?' ,
66+ choices = [
67+ Choice ('Upload all files in directory' , 'all' ),
68+ Choice ('Choose files from a list' , 'select' ),
69+ Choice ('Specify a glob pattern' , 'glob' ),
70+ ]
71+ )
72+ input_params ['files' ] = get_files_in_directory (input_params ['data_directory' ])
73+ if upload_method == 'select' :
74+ input_params ['files' ] = ask (
75+ 'checkbox' ,
76+ 'Select the files you wish to upload' ,
77+ choices = input_params ['files' ]
78+ )
79+ elif upload_method == 'glob' :
80+ matching_files = None
81+ while not matching_files :
82+ glob_pattern = ask ('text' , 'Glob pattern:' )
83+ matching_files = [f for f in input_params ['files' ] if fnmatch (f , glob_pattern )]
84+ if len (matching_files ) == 0 :
85+ print ('Glob pattern does not match any files, please specify another' )
86+
87+ input_params ['files' ] = matching_files
88+
89+ confirm_data_directory (input_params ['data_directory' ], input_params ['files' ])
9790
9891 input_params ['process' ] = ask_process (processes , input_params .get ('process' ))
9992
10093 data_directory_name = Path (input_params ['data_directory' ]).name
10194 default_name = input_params .get ('name' ) or data_directory_name
102- input_params ['name' ] = ask_name (default_name )
103- input_params ['description' ] = ask_description (input_params .get ('description' ))
95+ input_params ['name' ] = ask (
96+ 'text' ,
97+ 'What is the name of this dataset?' ,
98+ default = default_name ,
99+ validate = lambda val : len (val .strip ()) > 0 or 'Please enter a name'
100+ )
101+ input_params ['description' ] = ask (
102+ 'text' ,
103+ 'Enter a description of the dataset (optional)' ,
104+ default = input_params .get ('description' ) or ''
105+ )
106+
104107 return input_params
0 commit comments