Skip to content

Commit d832e75

Browse files
committed
Added warning popups.
1 parent 6622736 commit d832e75

File tree

3 files changed

+123
-87
lines changed

3 files changed

+123
-87
lines changed

ConversionRules/Warnings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"PlaySound": "No longer supported. Create a SoundContainer with CreateSoundContainer in the appropriate Create function.",
3+
}

Python/convert.py

Lines changed: 114 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55

66
from Python import shared_globals as cfg
77

8-
98
progress = 0
109
total_progress = 0
10+
11+
warnings_file_name = "Warnings.json"
12+
warnings_path = os.path.join("ConversionRules", warnings_file_name)
13+
warnings_available = os.path.isfile(warnings_path)
14+
1115
conversion_rules = {}
16+
warning_rules = {}
17+
warnings = []
1218

1319

1420
# TODO: Move to shared_globals.py
@@ -25,20 +31,22 @@ def resource_path(relative_path):
2531
output_folder = ".." if getattr(sys, 'frozen', False) else "Output"
2632

2733

28-
def load_conversion_rules():
34+
def load_conversion_and_warning_rules():
2935
json_parser = JsonComment(json)
3036

3137
json_files_found = 0
3238
try:
3339
for name in os.listdir("ConversionRules"):
34-
if name.endswith(".json"):
35-
path = os.path.join("ConversionRules", name)
36-
with open(path) as f:
37-
json_files_found += 1
38-
conversion_rules.update(json_parser.load(f))
40+
if name.endswith(".json") and name != warnings_file_name:
41+
json_files_found += 1
42+
with open(os.path.join("ConversionRules", name)) as f:
43+
conversion_rules.update(json_parser.load(f))
44+
if warnings_available:
45+
with open(warnings_path) as f:
46+
warning_rules.update(json_parser.load(f))
3947
except:
4048
check_github_button_clicked_and_exit(cfg.sg.Popup("The 'ConversionRules' folder wasn't found next to this executable. You can get the missing folder from the Legacy Mod Converter GitHub repo.", title="Missing ConversionRules folder", custom_text="Go to GitHub"))
41-
49+
4250
if json_files_found == 0:
4351
check_github_button_clicked_and_exit(cfg.sg.Popup("The 'ConversionRules' folder didn't contain any JSON files. You can get the JSON files from the Legacy Mod Converter GitHub repo.", title="Missing JSON files", custom_text="Go to GitHub"))
4452

@@ -51,147 +59,163 @@ def check_github_button_clicked_and_exit(clicked_github_button):
5159

5260

5361
def convert():
54-
global progress, total_progress, output_folder
62+
global progress, total_progress, output_folder, warnings
5563

5664
time_start = time.time()
5765

58-
input_folder = cfg.sg.user_settings_get_entry("input_folder")
66+
input_folder_path = cfg.sg.user_settings_get_entry("input_folder")
67+
true_input_folder_path = os.path.join(input_folder_path, os.pardir) # TODO: Better variable name.
5968

60-
unzip(input_folder)
69+
unzip(input_folder_path)
6170

62-
total_progress = get_total_progress(input_folder)
71+
total_progress = get_total_progress(input_folder_path)
6372

64-
for input_folder_path, input_subfolders, full_filename_list in os.walk(input_folder):
65-
mod_subfolder = get_mod_subfolder(input_folder, input_folder_path)
73+
for input_subfolder_path, input_subfolders, input_subfiles in os.walk(input_folder_path):
74+
mod_subfolder = get_mod_subfolder(input_folder_path, input_subfolder_path, true_input_folder_path)
6675
output_subfolder = os.path.join(output_folder, mod_subfolder)
6776

6877
try_print_mod_name(mod_subfolder)
69-
create_folder(input_folder_path, output_subfolder)
70-
process_file(full_filename_list, input_folder_path, output_subfolder)
78+
create_folder(input_subfolder_path, output_subfolder)
79+
process_file(input_subfiles, input_subfolder_path, output_subfolder, input_folder_path)
7180

7281
if cfg.sg.user_settings_get_entry("output_zips"):
73-
create_zips(input_folder, output_folder)
82+
create_zips(input_folder_path, output_folder)
83+
84+
if len(warnings) > 0:
85+
warnings_popup()
7486

7587
progress = 0
7688
total_progress = 0
89+
warnings = []
7790

7891
elapsed = math.floor(time.time() - time_start)
7992
if cfg.sg.user_settings_get_entry("play_finish_sound"):
8093
playsound(finishSoundPath)
8194
print("Finished in {} {}".format(elapsed, pluralize("second", elapsed)))
8295

8396

84-
def unzip(input_folder):
85-
for f in os.listdir(input_folder):
86-
zip_path = os.path.join(input_folder, f)
97+
def unzip(input_folder_path):
98+
for f in os.listdir(input_folder_path):
99+
zip_path = os.path.join(input_folder_path, f)
87100
if zipfile.is_zipfile(zip_path):
88101
with zipfile.ZipFile(zip_path) as item:
89-
item.extractall(input_folder)
102+
item.extractall(input_folder_path)
90103
os.remove(zip_path)
91104

92105

93-
def get_total_progress(input_folder):
94-
if input_folder.endswith(".rte"):
106+
def get_total_progress(input_folder_path):
107+
if input_folder_path.endswith(".rte"):
95108
mod_count = 1
96109
else:
97-
mod_count = len([name for name in os.listdir(input_folder) if os.path.isdir(os.path.join(input_folder, name))])
110+
mod_count = len([name for name in os.listdir(input_folder_path) if os.path.isdir(os.path.join(input_folder_path, name))])
98111

99112
return mod_count * 2 if cfg.sg.user_settings_get_entry("output_zips") else mod_count
100113

101114

102-
def get_mod_subfolder(input_folder, input_folder_path):
103-
if input_folder.endswith(".rte"):
104-
return os.path.relpath(input_folder_path, os.path.join(input_folder, os.pardir))
115+
def get_mod_subfolder(input_folder_path, input_subfolder_path, true_input_folder_path):
116+
if input_folder_path.endswith(".rte"):
117+
return os.path.relpath(input_subfolder_path, true_input_folder_path)
105118
else:
106-
return os.path.relpath(input_folder_path, input_folder)
119+
return os.path.relpath(input_subfolder_path, input_folder_path)
107120

108121

109122
def try_print_mod_name(mod_subfolder):
110-
input_folder_path_tuple = pathlib.Path(mod_subfolder).parts
123+
input_subfolder_path_tuple = pathlib.Path(mod_subfolder).parts
111124

112-
if len(input_folder_path_tuple) == 1:
113-
print("Converting '{}'".format(input_folder_path_tuple[0]))
125+
if len(input_subfolder_path_tuple) == 1:
126+
print("Converting '{}'".format(input_subfolder_path_tuple[0]))
114127
update_progress()
115128

116129

117130
def update_progress():
118-
global progress, total_progress
131+
global progress
119132
progress += 1
120133
cfg.progress_bar.UpdateBar(progress % total_progress, total_progress)
121134

122135

123-
def create_folder(input_folder_path, output_subfolder):
124-
# Prevents putting the input_folder itself into the output_subfolder.
125-
# if input_folder_path != cfg.sg.user_settings_get_entry("input_folder"):
126-
136+
def create_folder(input_subfolder_path, output_subfolder):
127137
try:
128138
os.makedirs(output_subfolder)
129139
except FileExistsError:
130140
pass
131141

132142

133-
def process_file(full_filename_list, input_folder_path, output_subfolder):
134-
for full_filename in full_filename_list:
143+
def process_file(input_subfiles, input_subfolder_path, output_subfolder, input_folder_path):
144+
for full_filename in input_subfiles:
135145
filename, file_extension = os.path.splitext(full_filename)
136146

137147
# The ".empty" file exists so otherwise empty folders can be added to Git.
138148
if filename == ".empty":
139149
continue
140150

141-
input_file_path = os.path.join(input_folder_path, full_filename)
151+
input_file_path = os.path.join(input_subfolder_path, full_filename)
142152
output_file_path = os.path.join(output_subfolder, full_filename)
143153

144154
if file_extension in (".ini", ".lua"):
145-
create_converted_file(input_file_path, output_file_path)
155+
create_converted_file(input_file_path, output_file_path, input_folder_path)
146156
else:
147157
shutil.copyfile(input_file_path, output_file_path)
148158

149159

150-
def create_converted_file(input_file_path, output_file_path):
160+
def create_converted_file(input_file_path, output_file_path, input_folder_path):
151161
try:
152162
with open(input_file_path, "r") as file_in:
153163
with open(output_file_path, "w") as file_out:
154-
all_lines = regex_replace(file_in.read())
155-
for old_str, new_str in conversion_rules.items():
156-
all_lines = all_lines.replace(old_str, new_str)
157-
all_lines = regex_replace_bmps_and_wavs(all_lines)
158-
file_out.write(all_lines)
164+
all_lines_list = []
165+
file_path = os.path.relpath(input_file_path, input_folder_path)
166+
167+
line_number = 0
168+
for line in file_in:
169+
line_number += 1
170+
171+
line = regex_replace(line)
172+
for old_str, new_str in conversion_rules.items():
173+
line = line.replace(old_str, new_str)
174+
all_lines_list.append(line)
175+
176+
if warnings_available:
177+
for old_str, new_str in warning_rules.items():
178+
if old_str in line:
179+
warnings.append("'{}' line {}: {} -> {}".format(file_path, line_number, old_str, new_str))
180+
181+
all_lines_str = "".join(all_lines_list)
182+
file_out.write(regex_replace_bmps_and_wavs(all_lines_str))
159183
except:
160184
shutil.copyfile(input_file_path, output_file_path)
161185

162186

163-
def regex_replace(all_lines):
164-
all_lines = simple_replace(all_lines, "Framerate = (.*)", "SpriteAnimMode = 7")
165-
all_lines = simple_replace(all_lines, "\tPlayerCount = (.*)\n", "")
166-
all_lines = simple_replace(all_lines, "\tTeamCount = (.*)\n", "")
187+
def regex_replace(line):
188+
line = simple_replace(line, "Framerate = (.*)", "SpriteAnimMode = 7")
189+
line = simple_replace(line, "\tPlayerCount = (.*)\n", "")
190+
line = simple_replace(line, "\tTeamCount = (.*)\n", "")
167191

168-
all_lines = specific_replace(all_lines, regex_replace_particle, False, "ParticleNumberToAdd = (.*)\n\tAddParticles = (.*)\n\t\tCopyOf = (.*)\n", "AddGib = Gib\n\t\tGibParticle = {}\n\t\t\tCopyOf = {}\n\t\tCount = {}\n")
169-
all_lines = specific_replace(all_lines, regex_replace_sound_priority, True, " Sound(((?! Sound).)*)Priority", " Sound{}// Priority")
170-
all_lines = specific_replace(all_lines, regex_use_capture, False, "FundsOfTeam(.*) =", "Team{}Funds =")
171-
# all_lines = specific_replace(all_lines, regex_replace_playsound, False, "", "")
192+
line = specific_replace(line, regex_replace_particle, False, "ParticleNumberToAdd = (.*)\n\tAddParticles = (.*)\n\t\tCopyOf = (.*)\n", "AddGib = Gib\n\t\tGibParticle = {}\n\t\t\tCopyOf = {}\n\t\tCount = {}\n")
193+
line = specific_replace(line, regex_replace_sound_priority, True, " Sound(((?! Sound).)*)Priority", " Sound{}// Priority")
194+
line = specific_replace(line, regex_use_capture, False, "FundsOfTeam(.*) =", "Team{}Funds =")
195+
# line = specific_replace(line, regex_replace_playsound, False, "", "")
172196

173-
return all_lines
197+
return line
174198

175199

176-
def simple_replace(all_lines, pattern, replacement):
177-
matches = re.findall(pattern, all_lines)
200+
def simple_replace(line, pattern, replacement):
201+
matches = re.findall(pattern, line)
178202
if len(matches) > 0:
179-
return re.sub(pattern, replacement, all_lines)
180-
return all_lines
203+
return re.sub(pattern, replacement, line)
204+
return line
181205

182206

183-
def specific_replace(all_lines, fn, dotall, pattern, replacement):
184-
# TODO: Refactor so .findall can take dotall as an argument directly.
207+
def specific_replace(line, fn, dotall, pattern, replacement):
208+
# TODO: Refactor so .findall takes re.DOTALL as an argument directly.
185209
if dotall:
186-
matches = re.findall(pattern, all_lines, re.DOTALL)
210+
matches = re.findall(pattern, line, re.DOTALL)
187211
else:
188-
matches = re.findall(pattern, all_lines)
212+
matches = re.findall(pattern, line)
189213
if len(matches) > 0:
190-
return fn(all_lines, pattern, replacement, matches)
191-
return all_lines
214+
return fn(line, pattern, replacement, matches)
215+
return line
192216

193217

194-
def regex_replace_particle(all_lines, pattern, replacement, matches):
218+
def regex_replace_particle(line, pattern, replacement, matches):
195219
# matches == [(4, "foo", "bar"), (2, "baz", "bee")]
196220
new = [item for tup in matches for item in tup]
197221
# new == [4, "foo", "bar", 2, "baz", "bee"]
@@ -201,46 +225,46 @@ def regex_replace_particle(all_lines, pattern, replacement, matches):
201225
new[1::3], new[2::3], new[0::3]
202226

203227
# new == ["foo", "bar", 4, "baz", "bee", 2]
204-
return re.sub(pattern, replacement, all_lines).format(*new)
228+
return re.sub(pattern, replacement, line).format(*new)
205229

206230

207-
def regex_replace_sound_priority(all_lines, pattern, replacement, matches):
231+
def regex_replace_sound_priority(line, pattern, replacement, matches):
208232
# TODO: This pattern returns two items in each tuple, while we only need the first. Create a better pattern.
209233
# https://stackoverflow.com/a/406408/13279557
210234
# https://regex101.com/r/NdKaWs/2
211235

212236
# matches == [(4, "foo"), (2, "bar")]
213237
new = [item for tup in matches for item in tup][::2]
214238
# new == [4, 2]
215-
return re.sub(pattern, replacement, all_lines, flags=re.DOTALL).format(*new)
239+
return re.sub(pattern, replacement, line, flags=re.DOTALL).format(*new)
216240

217241

218-
def regex_use_capture(all_lines, pattern, replacement, matches):
219-
return re.sub(pattern, replacement, all_lines).format(*matches)
242+
def regex_use_capture(line, pattern, replacement, matches):
243+
return re.sub(pattern, replacement, line).format(*matches)
220244

221245

222-
# def regex_replace_playsound(all_lines, pattern, replacement, matches):
223-
# return all_lines
246+
# def regex_replace_playsound(line, pattern, replacement, matches):
247+
# return line
224248
# # TODO:
225249
# # AudioMan:PlaySound("ModName.rte/Folder/SoundName.wav", SceneMan:TargetDistanceScalar(self.Pos), false, true, -1)
226250
# # to
227251
# # AudioMan:PlaySound("ModName.rte/Folder/SoundName.wav", self.Pos) -- Cut everything and leave the thing inside the brackets after SceneMan:TargetDistanceScalar
228252

229253

230-
def regex_replace_bmps_and_wavs(all_lines):
231-
all_lines = specific_replace(all_lines, regex_use_capture, False, "Base\.rte(.*?)\.bmp", "Base.rte{}.png")
232-
all_lines = specific_replace(all_lines, regex_use_capture, False, "base\.rte(.*?)\.bmp", "Base.rte{}.png")
233-
all_lines = specific_replace(all_lines, regex_use_capture, False, "Base\.rte(.*?)\.wav", "Base.rte{}.flac")
234-
all_lines = specific_replace(all_lines, regex_use_capture, False, "base\.rte(.*?)\.wav", "Base.rte{}.flac")
235-
return all_lines
254+
def regex_replace_bmps_and_wavs(line):
255+
line = specific_replace(line, regex_use_capture, False, "Base\.rte(.*?)\.bmp", "Base.rte{}.png")
256+
line = specific_replace(line, regex_use_capture, False, "base\.rte(.*?)\.bmp", "Base.rte{}.png")
257+
line = specific_replace(line, regex_use_capture, False, "Base\.rte(.*?)\.wav", "Base.rte{}.flac")
258+
line = specific_replace(line, regex_use_capture, False, "base\.rte(.*?)\.wav", "Base.rte{}.flac")
259+
return line
236260

237261

238-
def create_zips(input_folder, output_folder):
239-
if input_folder.endswith(".rte"):
240-
create_single_zip(Path(input_folder).name, output_folder)
262+
def create_zips(input_folder_path, output_folder):
263+
if input_folder_path.endswith(".rte"):
264+
create_single_zip(Path(input_folder_path).name, output_folder)
241265
else:
242266
# TODO: Move check if it's a directory out of this loop.
243-
folder_names = [f for f in os.listdir(cfg.sg.user_settings_get_entry("input_folder")) if os.path.isdir(os.path.join(output_folder, f))]
267+
folder_names = [f for f in os.listdir(input_folder_path) if os.path.isdir(os.path.join(output_folder, f))]
244268
for mod_name in folder_names:
245269
create_single_zip(mod_name, output_folder)
246270

@@ -253,5 +277,12 @@ def create_single_zip(mod_name, output_folder):
253277
update_progress()
254278

255279

280+
def warnings_popup():
281+
if warnings_available:
282+
w = max(30, len(max(warnings, key=len)))
283+
h = min(50, len(warnings)) + 1 # + 1 necessary because popup_scrolled adds an extra line
284+
cfg.sg.popup_scrolled("\n".join(warnings), title="Lines needing manual replacing", size=(w, h), button_color=cfg.sg.theme_button_color(), background_color=cfg.sg.theme_background_color())
285+
286+
256287
def pluralize(word, count):
257288
return word + "s" if count != 1 else word

Python/gui.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def init_window_theme():
2323
sg.theme("DarkGrey14")
2424
sg.theme_input_background_color(path_set_color)
2525
sg.theme_progress_bar_color((progress_bar_color, sg.theme_progress_bar_color()[1]))
26+
sg.theme_button_color((sg.theme_text_color(), "#2a3948"))
2627

2728

2829
def init_window():
@@ -54,6 +55,7 @@ def init_window():
5455

5556
play_finish_sound_setting = sg.user_settings_get_entry("play_finish_sound")
5657
sg.user_settings_set_entry("play_finish_sound", True if play_finish_sound_setting == None else play_finish_sound_setting)
58+
# print(sg.DEFAULT_FONT)
5759

5860
options_column = [
5961
[sg.Frame(layout=[
@@ -84,9 +86,9 @@ def init_window():
8486
]
8587

8688
cfg.sg = sg
87-
convert.load_conversion_rules()
89+
convert.load_conversion_and_warning_rules()
8890

89-
window = sg.Window("Legacy Mod Converter - v1.0", layout, icon=resource_path("Media/cclmc-icon.ico"), button_color=(sg.theme_text_color(), "#2a3948"))
91+
window = sg.Window("Legacy Mod Converter - v1.0", layout, icon=resource_path("Media/cclmc-icon.ico"))
9092
cfg.progress_bar = window["-PROGRESS BAR-"]
9193

9294
return window
@@ -109,9 +111,9 @@ def run_window(window):
109111
window[event](background_color = sg.theme_input_background_color())
110112

111113
elif event == "-OUTPUT ZIPS-":
112-
sg.user_settings_set_entry("output_zips", values["-OUTPUT ZIPS-"])
114+
sg.user_settings_set_entry("output_zips", values[event])
113115
elif event == "-PLAY FINISH SOUND-":
114-
sg.user_settings_set_entry("play_finish_sound", values["-PLAY FINISH SOUND-"])
116+
sg.user_settings_set_entry("play_finish_sound", values[event])
115117

116118
elif event == "-CONVERT-":
117119
if sg.user_settings_get_entry("input_folder") not in (None, ""):

0 commit comments

Comments
 (0)