-
Notifications
You must be signed in to change notification settings - Fork 0
/
vs_filenames.py
167 lines (129 loc) · 5.05 KB
/
vs_filenames.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import os
import tempfile
import random
import sys
import math
import shutil
FILES_ORIGINAL = []
FILES_UPDATED = []
def main(path: str, lacks_vs_code: bool):
"""
Main function
@param path path to the directory to rename files in
@param lacks_vs_code if true, the default editor will be used instead of vscode
"""
# validate path
if not os.path.isdir(path):
raise NotADirectoryError("Path is not a directory!")
# parse args
print("Using path " + path)
# enumerate files and store into FILES
for file in os.scandir(path):
FILES_ORIGINAL.append(file.name)
# create txt file with the file names
path = create_filelist_txt()
# use the default editor if vscode is not found
if lacks_vs_code:
print("Make your changes then press enter to continue")
os.system(path)
input()
else:
# open temporary file in vscode
print("Make your changes then close the file to continue")
os.system("code -w " + path)
# get and rename files
get_updated_names(path)
update_file_names()
# delete temporary file
try:
os.remove(path)
except PermissionError:
print("Permission denied while deleting the temporary file " + path)
sys.exit(1)
except OSError:
print("Couldn't delete the temporary file " + path)
sys.exit(1)
def create_filelist_txt() -> str:
"""
Create a temporary file containing the names of the files in the cwd
@return path to the temporary file
"""
with tempfile.TemporaryDirectory() as temp_dir:
# random file name to avoid conflicts
f_name = temp_dir + (str)(math.floor(random.random() * 10)) + '.txt'
# write the file names to the temporary file
with open(f_name, 'w', encoding="utf-8") as file:
for file_name in FILES_ORIGINAL:
file.write(file_name + '\n')
return f_name
def get_updated_names(path: str):
"""
Get the new file names from the temporary file and store it
@param path path to the temporary file to use
"""
try:
with open(path, 'r', encoding="utf-8") as file:
file.seek(0)
# get new file names
for line in file.readlines():
FILES_UPDATED.append(line)
except FileNotFoundError:
print("File not found! Was it deleted..?")
sys.exit(1)
except PermissionError:
print("Permission denied when reading " + path)
sys.exit(1)
def update_file_names():
"""
Update the file names of each file in the cwd given the new names
"""
# make sure the number of files hasn't changed
assert len(FILES_ORIGINAL) == len(
FILES_UPDATED), "Don't change the number of lines in the file!"
i = 0 # quick hack to avoid conflicting file names
for old_name, new_name in zip(FILES_ORIGINAL, FILES_UPDATED):
# detect edge case where the file name is the same
new = new_name.strip()
if os.path.isfile(new) and (new != old_name):
new = str(i) + new
i += 1 # keeps the file name unique
# rename the file and handle errors
try:
os.rename(old_name, new)
except PermissionError:
print("Permission denied when renaming " + old_name + " to " + new)
# ensures that the file name is valid, e.g., length, invalid characters
except OSError:
print("Error renaming " + old_name + " to " + new + "!")
def entry():
"""Entry point for the program
"""
import argparse
# parse args
p = argparse.ArgumentParser(description="Mass rename files with vscode.",
formatter_class=argparse.RawTextHelpFormatter,
epilog="""
The program will open a temporary file in vscode containing the names of the files in the cwd.
If VS Code is not found in the PATH, the temporary file will be opened in the default text editor, and you'll have to close it manually, then press enter.
The order of the lines matter and correspond one-to-one to the new names of the files.
Duplicates are handled by prepending a number to the end of the file name but this is handled poorly so don't do it.
After renaming to your hearts content, close the file and the renaming shall commence.
Use with caution! There is no undo nor is there testing. You have been warned.
""")
p.add_argument("-path",
action="store",
type=str,
dest="path",
default=os.getcwd(),
help="""Path to the directory to rename files in.
By default, the current working directory is used.""")
# check if vscode is in the path
p.add_argument("-no-code",
action=argparse.BooleanOptionalAction,
type=bool,
default=not (shutil.which("code")),
help="If set to true, the default editor will be used instead of vscode.")
args = p.parse_args()
main(args.path, args.no_code)
if __name__ == "__main__":
entry()