Skip to content

Commit 2a5b56a

Browse files
committed
reformatted code & added requirements file
1 parent 5e182f9 commit 2a5b56a

File tree

4 files changed

+169
-153
lines changed

4 files changed

+169
-153
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/__pycache__
2+
/.venv
3+
/.vscode

file_renamer.py

+77-72
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,40 @@
88

99

1010
def get_counts(target_path):
11-
'''Accepts a path. Returns the number of files and sub-directories
12-
contained in the path.'''
11+
"""Accepts a path. Returns the number of files and sub-directories
12+
contained in the path."""
1313
file_count = 0
1414
dir_count = 0 # count does not include 'target_path' directory
1515

1616
for _, dirs, files in os.walk(target_path):
1717
# remove hidden files and directories
18-
files = [file for file in files if not file[0] == '.']
19-
dirs[:] = [dir for dir in dirs if not dir[0] == '.']
18+
files = [file for file in files if not file[0] == "."]
19+
dirs[:] = [dir for dir in dirs if not dir[0] == "."]
2020

2121
file_count += len(files)
2222
dir_count += len(dirs)
2323

2424
return [file_count, dir_count]
2525

2626

27-
is_script = __name__ == '__main__'
27+
is_script = __name__ == "__main__"
2828

2929

3030
# only run parser logic if file is run as a script
3131
if is_script:
3232
# define the parser
33-
parser = argparse.ArgumentParser(description='Parse arguments from CLI.')
33+
parser = argparse.ArgumentParser(description="Parse arguments from CLI.")
3434

3535
# define arguments
36-
parser.add_argument('--target-path', action="store",
37-
dest='target_path', default="null")
38-
parser.add_argument('--string', action="store",
39-
dest='string', default="null")
40-
parser.add_argument('--replacement', action="store",
41-
dest='replacement', default="null")
42-
parser.add_argument('--lowercase', action="store",
43-
dest='lowercase', default=False)
44-
parser.add_argument('--uppercase', action="store",
45-
dest='uppercase', default=False)
36+
parser.add_argument(
37+
"--target-path", action="store", dest="target_path", default="null"
38+
)
39+
parser.add_argument("--string", action="store", dest="string", default="null")
40+
parser.add_argument(
41+
"--replacement", action="store", dest="replacement", default="null"
42+
)
43+
parser.add_argument("--lowercase", action="store", dest="lowercase", default=False)
44+
parser.add_argument("--uppercase", action="store", dest="uppercase", default=False)
4645

4746
args = parser.parse_args()
4847

@@ -53,13 +52,15 @@ def get_counts(target_path):
5352
lowercase = args.lowercase
5453
uppercase = args.uppercase
5554

56-
replacements = {
57-
string: replacement
58-
}
55+
replacements = {string: replacement}
5956

6057
if target_path == "null" or string == "null" or replacement == "null":
61-
print(("Please specify an argument for "
62-
"--target-path, --string, and --replacement."))
58+
print(
59+
(
60+
"Please specify an argument for "
61+
"--target-path, --string, and --replacement."
62+
)
63+
)
6364
sys.exit()
6465

6566
if not os.path.exists(target_path):
@@ -71,7 +72,7 @@ def get_counts(target_path):
7172

7273
# set if file is run as a module
7374
else:
74-
target_path = ''
75+
target_path = ""
7576

7677
# substring/regex replacement rules will be built here from UI
7778
replacements = {}
@@ -81,53 +82,56 @@ def get_counts(target_path):
8182

8283

8384
def set_confirmation(target_path, file_count, dir_count):
84-
'''Accepts a path, file count, and a directory count. Used when run as a
85+
"""Accepts a path, file count, and a directory count. Used when run as a
8586
script to display to user the number of files and directories that will be
86-
inspected. Returns True if user confirms.'''
87+
inspected. Returns True if user confirms."""
8788

88-
print(f'\nSelected target directory: {target_path}')
89+
print(f"\nSelected target directory: {target_path}")
8990

90-
subdirs_string = f', including {dir_count} sub-directories,'
91-
count_string = (f'\n{file_count} files'
92-
f'{subdirs_string if dir_count else ""} '
93-
'will be inspected.\n')
91+
subdirs_string = f", including {dir_count} sub-directories,"
92+
count_string = (
93+
f"\n{file_count} files"
94+
f'{subdirs_string if dir_count else ""} '
95+
"will be inspected.\n"
96+
)
9497

9598
if file_count:
9699
print(count_string)
97100
else:
98-
print('\nOperation aborted: No files found.')
101+
print("\nOperation aborted: No files found.")
99102
sys.exit()
100103

101-
confirm_string = ('Are you sure you wish to proceed '
102-
'with rename operation? (y/n): ')
104+
confirm_string = (
105+
"Are you sure you wish to proceed " "with rename operation? (y/n): "
106+
)
103107
confirm_input = input(confirm_string)
104108

105-
return confirm_input.lower() == 'y' or confirm_input.lower() == 'yes'
109+
return confirm_input.lower() == "y" or confirm_input.lower() == "yes"
106110

107111

108-
def perform_rename(path, replacements, lowercase=False,
109-
uppercase=False, base_log=None):
110-
'''Accepts a path and optional lowercase or uppercase enforcement arguments.
112+
def perform_rename(path, replacements, lowercase=False, uppercase=False, base_log=None):
113+
"""Accepts a path and optional lowercase or uppercase enforcement arguments.
111114
Performs the rename logic as well as setting up the JSON log data.
112-
'base_log' is used to pass the base JSON log data to the recursive calls.'''
115+
'base_log' is used to pass the base JSON log data to the recursive calls."""
113116
# raise a ValueError if user passed True for
114117
# 'lowercase' AND 'uppercase' arguments
115118
if lowercase and uppercase:
116-
error_string = ("'lowercase' OR 'uppercase' argument can be True, "
117-
'but not both.')
119+
error_string = (
120+
"'lowercase' OR 'uppercase' argument can be True, " "but not both."
121+
)
118122
raise ValueError(error_string)
119123

120124
# if 'base_log' argument is not passed, current path is 'target_path'
121125
# this means it's the first execution of 'perform_rename()'
122126
is_target_path = base_log is None
123127
if is_target_path:
124128
base_log = {
125-
'timestamp': datetime.now(),
126-
'directories_inspected': 0,
127-
'files_inspected': 0,
128-
'files_renamed': 0,
129-
'replacement_rules': replacements,
130-
'target_path': path,
129+
"timestamp": datetime.now(),
130+
"directories_inspected": 0,
131+
"files_inspected": 0,
132+
"files_renamed": 0,
133+
"replacement_rules": replacements,
134+
"target_path": path,
131135
}
132136

133137
files = []
@@ -137,70 +141,71 @@ def perform_rename(path, replacements, lowercase=False,
137141
with os.scandir(path) as iterator:
138142
for item in iterator:
139143
# exclude hidden files and directories
140-
if not item.name.startswith('.'):
144+
if not item.name.startswith("."):
141145
# add any sub-directories to 'children' of current directory
142146
if item.is_dir():
143147
children.append(
144-
perform_rename(item.path, replacements, lowercase,
145-
uppercase, base_log))
148+
perform_rename(
149+
item.path, replacements, lowercase, uppercase, base_log
150+
)
151+
)
146152
# if 'item' is a file
147153
else:
148-
base_log['files_inspected'] += 1
154+
base_log["files_inspected"] += 1
149155
for substring, replacement in replacements.items():
150156
if substring in item.name:
151-
new_name = item.name.replace(
152-
substring, replacement)
157+
new_name = item.name.replace(substring, replacement)
153158
if lowercase:
154159
new_name = new_name.lower()
155160
if uppercase:
156161
new_name = new_name.upper()
157162
new_path = os.path.join(path, new_name)
158163
os.rename(item.path, new_path)
159-
base_log['files_renamed'] += 1
160-
files.append({
161-
'original_name': item.name,
162-
'new_name': new_name,
163-
})
164+
base_log["files_renamed"] += 1
165+
files.append(
166+
{
167+
"original_name": item.name,
168+
"new_name": new_name,
169+
}
170+
)
164171
break
165172
else:
166173
# if 'item' is a hidden directory, continue
167174
continue
168175

169-
base_log['directories_inspected'] += 1
176+
base_log["directories_inspected"] += 1
170177

171178
# start building 'directory' object
172-
directory = {'directory': path}
179+
directory = {"directory": path}
173180
# add 'files' and 'children' to 'directory' object
174181
if files:
175-
directory.update({'files': files})
182+
directory.update({"files": files})
176183
if children:
177-
directory.update({'children': children})
184+
directory.update({"children": children})
178185
if is_target_path:
179-
rename_data = {'rename_data': [directory]}
186+
rename_data = {"rename_data": [directory]}
180187
# add 'base_log' keys/values to 'rename_data'
181188
directory = base_log | rename_data
182189

183190
return directory
184191

185192

186193
def run_renamer(target_path):
187-
'''Accepts a path argument. Performs rename operation and displays summary
188-
information to the user.'''
194+
"""Accepts a path argument. Performs rename operation and displays summary
195+
information to the user."""
196+
189197
def rename():
190198
# result will be set JSON log object
191-
result = perform_rename(target_path, replacements,
192-
lowercase, uppercase)
199+
result = perform_rename(target_path, replacements, lowercase, uppercase)
193200

194-
timestamp = result['timestamp']
201+
timestamp = result["timestamp"]
195202

196203
# create log file
197-
with open(f'renamer_log--{timestamp}.json', 'a') as log:
204+
with open(f"renamer_log--{timestamp}.json", "a") as log:
198205
log.write(json.dumps(result, indent=4, default=str))
199206

200-
files_renamed = (result['files_renamed']
201-
if result['files_renamed'] > 0 else "No")
202-
result_msg = (f'\nOperation completed: '
203-
f'{files_renamed} files were renamed.')
207+
files_renamed = result["files_renamed"] if result["files_renamed"] > 0 else "No"
208+
result_msg = f"\nOperation completed: " f"{files_renamed} files were renamed."
204209

205210
return result_msg
206211

@@ -210,7 +215,7 @@ def rename():
210215
result_msg = rename()
211216
print(result_msg)
212217
else:
213-
print('\nOperation aborted: Failed to confirm.')
218+
print("\nOperation aborted: Failed to confirm.")
214219
else:
215220
return rename()
216221

0 commit comments

Comments
 (0)