Skip to content

Commit bb0939d

Browse files
committed
-
1 parent 40fe588 commit bb0939d

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

source_py3/python_toolbox/file_tools.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'''Defines various tools related to temporary files.'''
55

66
import pathlib
7+
import os
78
import re
89

910
from 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+
6287
def 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,

source_py3/test_python_toolbox/test_file_tools/test_renaming_file.py renamed to source_py3/test_python_toolbox/test_file_tools/test_renaming.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,22 @@ def test():
5555
with pathlib.Path(last_file.name).open('r') as last_file_input:
5656
assert last_file_input.read() == string_to_write
5757

58+
folder_1 = file_tools.create_folder_renaming_if_taken(
59+
temporary_folder / 'woof'
60+
)
61+
folder_2 = file_tools.create_folder_renaming_if_taken(
62+
temporary_folder / 'woof'
63+
)
64+
folder_3 = file_tools.create_folder_renaming_if_taken(
65+
temporary_folder / 'woof'
66+
)
67+
68+
assert folder_1.name == 'woof'
69+
assert folder_2.name == 'woof (1)'
70+
assert folder_3.name == 'woof (2)'
71+
72+
assert get_file_names_set() == {'meow.txt', 'meow (1).txt',
73+
'meow (2).txt', 'meow (3).txt',
74+
'meow (4).txt', 'woof', 'woof (1)',
75+
'woof (2)'}
76+

0 commit comments

Comments
 (0)