2828 TopLevelFolder ,
2929 )
3030
31+ import paramiko
3132import yaml
3233
3334from datashuttle .configs import (
@@ -217,13 +218,13 @@ def create_folders(
217218 utils .log ("\n Formatting Names..." )
218219 ds_logger .log_names (["sub_names" , "ses_names" ], [sub_names , ses_names ])
219220
220- validation_templates = self .get_validation_templates ()
221+ name_templates = self .get_name_templates ()
221222
222223 format_sub , format_ses = self ._format_and_validate_names (
223224 top_level_folder ,
224225 sub_names ,
225226 ses_names ,
226- validation_templates ,
227+ name_templates ,
227228 bypass_validation ,
228229 allow_letters_in_sub_ses_values ,
229230 log = True ,
@@ -260,7 +261,7 @@ def _format_and_validate_names(
260261 top_level_folder : TopLevelFolder ,
261262 sub_names : Union [str , List [str ]],
262263 ses_names : Optional [Union [str , List [str ]]],
263- validation_templates : Dict ,
264+ name_templates : Dict ,
264265 bypass_validation : bool ,
265266 allow_letters_in_sub_ses_values : bool ,
266267 log : bool = True ,
@@ -269,7 +270,7 @@ def _format_and_validate_names(
269270 format_sub = formatting .check_and_format_names (
270271 sub_names ,
271272 "sub" ,
272- validation_templates ,
273+ name_templates ,
273274 bypass_validation ,
274275 allow_letters_in_sub_ses_values ,
275276 )
@@ -278,7 +279,7 @@ def _format_and_validate_names(
278279 format_ses = formatting .check_and_format_names (
279280 ses_names ,
280281 "ses" ,
281- validation_templates ,
282+ name_templates ,
282283 bypass_validation ,
283284 allow_letters_in_sub_ses_values ,
284285 )
@@ -294,7 +295,7 @@ def _format_and_validate_names(
294295 include_central = False ,
295296 display_mode = "error" ,
296297 log = log ,
297- validation_templates = validation_templates ,
298+ name_templates = name_templates ,
298299 allow_letters_in_sub_ses_values = allow_letters_in_sub_ses_values ,
299300 )
300301
@@ -819,27 +820,47 @@ def setup_ssh_connection(self) -> None:
819820 "setup-ssh-connection-to-central-server" , local_vars = locals ()
820821 )
821822
822- verified = ssh .verify_ssh_central_host_api (
823+ verified = ssh .verify_ssh_central_host (
823824 self .cfg ["central_host_id" ],
824825 self .cfg .hostkeys_path ,
825826 log = True ,
826827 )
827828
828829 if verified :
829- private_key_str = ssh .setup_ssh_key_api (self .cfg , log = True )
830-
831- self ._setup_rclone_central_ssh_config (private_key_str , log = True )
830+ ssh .setup_ssh_key (self .cfg , log = True )
831+ self ._setup_rclone_central_ssh_config (log = True )
832832
833833 rclone .check_successful_connection_and_raise_error_on_fail (
834834 self .cfg
835835 )
836836
837- utils .log_and_message (
838- "SSH key pair setup successfully. SSH key saved to the RClone config file."
839- )
840-
841837 ds_logger .close_log_filehandler ()
842838
839+ @requires_ssh_configs
840+ @check_is_not_local_project
841+ def write_public_key (self , filepath : str ) -> None :
842+ """Save the public SSH key to a specified filepath.
843+
844+ By default, only the SSH private key is stored in the
845+ datashuttle configs folder. Use this function to save
846+ the public key.
847+
848+ Parameters
849+ ----------
850+ filepath
851+ Full filepath (including filename) to write the
852+ public key to.
853+
854+ """
855+ key : paramiko .RSAKey
856+ key = paramiko .RSAKey .from_private_key_file (
857+ self .cfg .ssh_key_path .as_posix ()
858+ )
859+
860+ with open (filepath , "w" ) as public :
861+ public .write (key .get_base64 ())
862+ public .close ()
863+
843864 # -------------------------------------------------------------------------
844865 # Google Drive
845866 # -------------------------------------------------------------------------
@@ -1056,17 +1077,7 @@ def make_config_file(
10561077 ds_logger .close_log_filehandler ()
10571078
10581079 def update_config_file (self , ** kwargs ) -> None :
1059- """Update the configuration file.
1060-
1061- Parameters
1062- ----------
1063- **kwargs
1064- A dictionary of key-value pairs containing the config
1065- settings to update. For example,
1066- ``{"connection_method": "local_filesystem", "central_path": "/my/local/path"}``
1067- will update the ``connection_method`` and ``central_path`` settings.
1068-
1069- """
1080+ """Update the configuration file."""
10701081 if not self .cfg :
10711082 utils .log_and_raise_error (
10721083 "Must have a config loaded before updating configs." ,
@@ -1166,9 +1177,9 @@ def get_next_sub(
11661177 The next subject ID.
11671178
11681179 """
1169- validation_template = self .get_validation_templates ()
1170- validation_template_regexp = (
1171- validation_template ["sub" ] if validation_template ["on" ] else None
1180+ name_template = self .get_name_templates ()
1181+ name_template_regexp = (
1182+ name_template ["sub" ] if name_template ["on" ] else None
11721183 )
11731184
11741185 if self .is_local_project ():
@@ -1181,7 +1192,7 @@ def get_next_sub(
11811192 include_central = include_central ,
11821193 return_with_prefix = return_with_prefix ,
11831194 search_str = "sub-*" ,
1184- validation_template_regexp = validation_template_regexp ,
1195+ name_template_regexp = name_template_regexp ,
11851196 )
11861197
11871198 @check_configs_set
@@ -1215,9 +1226,9 @@ def get_next_ses(
12151226 The next session ID.
12161227
12171228 """
1218- validation_template = self .get_validation_templates ()
1219- validation_template_regexp = (
1220- validation_template ["ses" ] if validation_template ["on" ] else None
1229+ name_template = self .get_name_templates ()
1230+ name_template_regexp = (
1231+ name_template ["ses" ] if name_template ["on" ] else None
12211232 )
12221233
12231234 if self .is_local_project ():
@@ -1230,7 +1241,7 @@ def get_next_ses(
12301241 include_central = include_central ,
12311242 return_with_prefix = return_with_prefix ,
12321243 search_str = "ses-*" ,
1233- validation_template_regexp = validation_template_regexp ,
1244+ name_template_regexp = name_template_regexp ,
12341245 )
12351246
12361247 @check_configs_set
@@ -1245,38 +1256,36 @@ def is_local_project(self) -> bool:
12451256 # Name Templates
12461257 # -------------------------------------------------------------------------
12471258
1248- def get_validation_templates (self ) -> Dict :
1259+ def get_name_templates (self ) -> Dict :
12491260 """Return the regexp templates used for validation.
12501261
12511262 If the "on" key is set to `False`, template validation is not performed.
12521263
12531264 Returns
12541265 -------
1255- validation_templates
1256- e.g. {"validation_templates ": {"on": False, "sub": None, "ses": None}}
1266+ name_templates
1267+ e.g. {"name_templates ": {"on": False, "sub": None, "ses": None}}
12571268
12581269 """
12591270 settings = self ._load_persistent_settings ()
1260- return settings ["validation_templates " ]
1271+ return settings ["name_templates " ]
12611272
1262- def set_validation_templates (self , new_validation_templates : Dict ) -> None :
1273+ def set_name_templates (self , new_name_templates : Dict ) -> None :
12631274 """Update the persistent settings with new name templates.
12641275
1265- Name templates are regexp for that, when ``validation_templates ["on"]`` is
1276+ Name templates are regexp for that, when ``name_templates ["on"]`` is
12661277 set to ``True``, ``"sub"`` and ``"ses"`` names are validated against
12671278 the regexp contained in the dict.
12681279
12691280 Parameters
12701281 ----------
1271- new_validation_templates
1272- e.g. ``{"validation_templates ": {"on": False, "sub": None, "ses": None}}``
1282+ new_name_templates
1283+ e.g. ``{"name_templates ": {"on": False, "sub": None, "ses": None}}``
12731284 where ``"sub"`` or ``"ses"`` can be a regexp that subject and session
12741285 names respectively are validated against.
12751286
12761287 """
1277- self ._update_persistent_setting (
1278- "validation_templates" , new_validation_templates
1279- )
1288+ self ._update_persistent_setting ("name_templates" , new_name_templates )
12801289
12811290 # -------------------------------------------------------------------------
12821291 # Showers
@@ -1357,7 +1366,7 @@ def validate_project(
13571366 local_vars = locals (),
13581367 )
13591368
1360- validation_templates = self .get_validation_templates ()
1369+ name_templates = self .get_name_templates ()
13611370
13621371 if self .is_local_project ():
13631372 include_central = False
@@ -1371,7 +1380,7 @@ def validate_project(
13711380 top_level_folder_to_validate ,
13721381 include_central = include_central ,
13731382 display_mode = display_mode ,
1374- validation_templates = validation_templates ,
1383+ name_templates = name_templates ,
13751384 strict_mode = strict_mode ,
13761385 allow_letters_in_sub_ses_values = allow_letters_in_sub_ses_values ,
13771386 )
@@ -1569,13 +1578,11 @@ def _make_project_metadata_if_does_not_exist(self) -> None:
15691578 """
15701579 folders .create_folders (self .cfg .project_metadata_path , log = False )
15711580
1572- def _setup_rclone_central_ssh_config (
1573- self , private_key_str : str , log : bool
1574- ) -> None :
1581+ def _setup_rclone_central_ssh_config (self , log : bool ) -> None :
15751582 rclone .setup_rclone_config_for_ssh (
15761583 self .cfg ,
15771584 self .cfg .get_rclone_config_name ("ssh" ),
1578- private_key_str ,
1585+ self . cfg . ssh_key_path ,
15791586 log = log ,
15801587 )
15811588
@@ -1671,15 +1678,8 @@ def _update_settings_with_new_canonical_keys(self, settings: Dict) -> None:
16711678 Added keys:
16721679 v0.4.0: tui "overwrite_existing_files" and "dry_run"
16731680 """
1674- if "validation_templates" not in settings :
1675- if "name_templates" in settings :
1676- settings ["validation_templates" ] = settings .pop (
1677- "name_templates"
1678- )
1679- else :
1680- settings .update (
1681- canonical_configs .get_validation_templates_defaults ()
1682- )
1681+ if "name_templates" not in settings :
1682+ settings .update (canonical_configs .get_name_templates_defaults ())
16831683
16841684 canonical_tui_configs = canonical_configs .get_tui_config_defaults ()
16851685
0 commit comments