44'''Defines various tools related to temporary files.'''
55
66import pathlib
7+ import os
78import re
89
910from python_toolbox import cute_iter_tools
@@ -27,20 +28,20 @@ def _get_next_path(path):
2728 '''
2829 assert isinstance (path , pathlib .Path )
2930 suffix = path .suffix
30- suffixless_name = path .name [:- len (suffix )]
31- parent_with_separator = str (path )[:- len (path .name )]
32- assert pathlib .Path ('{}{}{}' .format (parent_with_separator ,
33- suffixless_name , suffix )) == path
34- match = numbered_name_pattern .match (suffixless_name )
31+ suffixless_last_part = path .parts [ - 1 ] [:- len (suffix )]
32+ head = str (path )[:- len (path .parts [ - 1 ] )]
33+ assert pathlib .Path ('{}{}{}' .format (head ,
34+ suffixless_last_part , suffix )) == path
35+ match = numbered_name_pattern .match (suffixless_last_part )
3536 if match :
3637 fixed_suffixless_name = '{} ({})' .format (
3738 match .group ('raw_name' ),
3839 int (match .group ('number' ))+ 1 ,
3940 )
4041 else :
41- fixed_suffixless_name = '{} (1)' .format (suffixless_name ,)
42+ fixed_suffixless_name = '{} (1)' .format (suffixless_last_part ,)
4243 return pathlib .Path (
43- '{}{}{}' .format (parent_with_separator , fixed_suffixless_name , suffix )
44+ '{}{}{}' .format (head , fixed_suffixless_name , suffix )
4445 )
4546
4647
@@ -59,14 +60,38 @@ def iterate_file_paths(path):
5960 path = _get_next_path (path )
6061
6162
63+ def create_folder_renaming_if_taken (path ):
64+ '''
65+ Create a new folder with name `path` for writing, renaming if name taken.
66+
67+ If the name given is "example", the new name would be "example
68+ (1)", and if that's taken "example (1)", and so on.
69+
70+ Returns a path object to the newly-created folder
71+ '''
72+ for path in cute_iter_tools .shorten (iterate_file_paths (pathlib .Path (path )),
73+ N_MAX_ATTEMPTS ):
74+ try :
75+ os .makedirs (str (path ), exist_ok = False )
76+ except OSError :
77+ pass
78+ else :
79+ return path
80+ else :
81+ raise Exception ("Exceeded {} tries, can't create folder {}" .format (
82+ N_MAX_ATTEMPTS ,
83+ path
84+ ))
85+
86+
6287def create_file_renaming_if_taken (path , mode = 'x' ,
6388 buffering = - 1 , encoding = None ,
6489 errors = None , newline = None ):
6590 '''
6691 Create a new file with name `path` for writing, renaming it if name taken.
6792
6893 If the name given is "example.zip", the new name would be "example
69- (1).zip", and if that's taken "example (1 ).zip", and so on.
94+ (1).zip", and if that's taken "example (2 ).zip", and so on.
7095
7196 Returns the file open and ready for writing. It's best to use this as a
7297 context manager similarly to `open` so the file would be closed.
@@ -94,7 +119,7 @@ def write_to_file_renaming_if_taken(path, data, mode='x',
94119 Write `data` to a new file with name `path`, renaming it if name taken.
95120
96121 If the name given is "example.zip", the new name would be "example
97- (1).zip", and if that's taken "example (1 ).zip", and so on.
122+ (1).zip", and if that's taken "example (2 ).zip", and so on.
98123 '''
99124 with create_file_renaming_if_taken (
100125 path , mode = mode , buffering = buffering , encoding = encoding , errors = errors ,
0 commit comments