Skip to content

Commit 7f92dfd

Browse files
Enhance menu display and error handling in ESP32 Ultra Flasher tool
1 parent e582054 commit 7f92dfd

File tree

1 file changed

+50
-37
lines changed

1 file changed

+50
-37
lines changed

flasher.py

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,43 @@ def __init__(self):
2929
self.config = configparser.ConfigParser()
3030
self.__load_menu_items()
3131

32+
def display_menu(self) -> None:
33+
try:
34+
print()
35+
36+
if len(self.menu_items) == 0:
37+
tprint.warning("No projects found in the 'esp32' folder.")
38+
tprint.warning("Please add your projects and try again.")
39+
exit()
40+
41+
tprint.info("Select a project to flash:")
42+
for idx, (item, error, _) in enumerate(self.menu_items):
43+
if error:
44+
tprint.warning(f" <{idx + 1}> {item}")
45+
else:
46+
tprint.info(f" <{idx + 1}> {item}")
47+
48+
selection = tprint.input("Enter a number to select, or 'exit' to quit: > ").strip()
49+
50+
if selection.lower() == 'exit':
51+
tprint.debug("Exiting...")
52+
exit()
53+
54+
try:
55+
selection = int(selection) - 1
56+
tprint.debug(f"Selection of user (index): {selection}")
57+
if 0 <= selection < len(self.menu_items):
58+
self.current_item = self.menu_items[selection]
59+
self.__handle_selection(self.current_item)
60+
else:
61+
tprint.warning("Invalid selection, try again.")
62+
self.display_menu()
63+
except ValueError:
64+
tprint.error("Invalid input, please enter a valid number or 'exit'.")
65+
self.display_menu()
66+
except Exception as e:
67+
tprint.error(f"Error displaying menu: {e}")
68+
3269
def __autogenerate_config(self, folder_path: str) -> None:
3370
try:
3471
bin_files = [f for f in os.listdir(folder_path) if f.endswith('.bin')]
@@ -136,42 +173,12 @@ def __validate_memory_addresses(self) -> None:
136173
try:
137174
settings = self.config['Settings']
138175
for key, value in settings.items():
139-
if key.endswith('.bin') and not (value.startswith('0x') and all(c in '0123456789abcdefABCDEF' for c in value[2:])):
176+
if key.endswith('.bin') and not (
177+
value.startswith('0x') and all(c in '0123456789abcdefABCDEF' for c in value[2:])):
140178
tprint.error(f"Invalid memory address: {value}. Address must be in hex format.")
141179
except Exception as e:
142180
tprint.error(f"Error validating memory addresses: {e}")
143181

144-
def display_menu(self) -> None:
145-
try:
146-
print()
147-
tprint.info("Select a project to flash:")
148-
for idx, (item, error, _) in enumerate(self.menu_items):
149-
if error:
150-
tprint.warning(f" <{idx + 1}> {item}")
151-
else:
152-
tprint.info(f" <{idx + 1}> {item}")
153-
154-
selection = tprint.input("Enter a number to select, or 'exit' to quit: > ").strip()
155-
156-
if selection.lower() == 'exit':
157-
tprint.debug("Exiting...")
158-
exit()
159-
160-
try:
161-
selection = int(selection) - 1
162-
tprint.debug(f"Selection of user (index): {selection}")
163-
if 0 <= selection < len(self.menu_items):
164-
self.current_item = self.menu_items[selection]
165-
self.__handle_selection(self.current_item)
166-
else:
167-
tprint.warning("Invalid selection, try again.")
168-
self.display_menu()
169-
except ValueError:
170-
tprint.error("Invalid input, please enter a valid number or 'exit'.")
171-
self.display_menu()
172-
except Exception as e:
173-
tprint.error(f"Error displaying menu: {e}")
174-
175182
def __handle_selection(self, item: tuple[str, str, list[str]]) -> None:
176183
folder_name, error, issues = item
177184
folder_path = os.path.join(self.esp32_folder, folder_name)
@@ -197,22 +204,22 @@ def __handle_selection(self, item: tuple[str, str, list[str]]) -> None:
197204
elif choice == '2':
198205
self.__autogenerate_config(folder_path)
199206
elif choice == '3':
200-
self._check_project(folder_name, folder_path)
207+
self.__check_project(folder_name, folder_path)
201208
else:
202209
tprint.warning("Invalid choice, returning to menu.")
203210
self.display_menu()
204211
else:
205-
self._flash_esp32(folder_name)
212+
self.__flash_esp32(folder_name)
206213

207-
def _check_project(self, folder_name: str, folder_path: str) -> None:
214+
def __check_project(self, folder_name: str, folder_path: str) -> None:
208215
refreshed_issues = self.__check_folder_for_issues(folder_path)
209216
for idx, (name, _, _) in enumerate(self.menu_items):
210217
if name == folder_name:
211218
error = True if refreshed_issues else False
212219
self.menu_items[idx] = (folder_name, error, refreshed_issues if error else None)
213220
break
214221

215-
def _flash_esp32(self, folder_name: str) -> None:
222+
def __flash_esp32(self, folder_name: str) -> None:
216223
"""Flash the ESP32 using the config.ini instructions."""
217224
folder_path = os.path.join(self.esp32_folder, folder_name)
218225
config_path = os.path.join(folder_path, 'config.ini')
@@ -329,14 +336,20 @@ def __check_for_memory_address_conflicts(self, bin_files: list[str]) -> list[str
329336
for bin_file in bin_files:
330337
address = self.config['Settings'].get(bin_file)
331338
if address in addresses:
332-
mem_conflicts.append(f"Memory address conflict: '{bin_file}' and '{addresses[address]}' are using the same address: {address}")
339+
mem_conflicts.append(
340+
f"Memory address conflict: '{bin_file}' and '{addresses[address]}' are using the same address: {address}")
333341
addresses[address] = bin_file
334342
return mem_conflicts
335343

336344

337345
if __name__ == "__main__":
338346
try:
339347
separator("ESP32 Ultra Flasher")
348+
if not os.path.exists("esp32"):
349+
os.mkdir("esp32")
350+
print()
351+
tprint.warning("The 'esp32' folder does not exist. We have recreated it so add your projects.")
352+
exit()
340353
flasher = ESP32UltraFlasher()
341354
flasher.display_menu()
342355
except KeyboardInterrupt:

0 commit comments

Comments
 (0)