Skip to content

Commit 2b09b83

Browse files
authored
Fix: bugs in util scripts (#62)
1 parent d47653e commit 2b09b83

2 files changed

Lines changed: 57 additions & 70 deletions

File tree

util/install_walter_modem/install_walter_modem.sh

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,82 +18,55 @@ spinner() {
1818
local delay=0.1
1919
local spinstr=('' '' '' '' '' '' '' '' '' '')
2020
local i=0
21-
tput civis 2>/dev/null # Hide cursor
21+
tput civis 2>/dev/null
2222
while kill -0 "$pid" 2>/dev/null; do
2323
printf "\r %s " "${spinstr[i]}"
2424
i=$(( (i+1) % ${#spinstr[@]} ))
2525
sleep $delay
2626
done
27-
printf "\r\033[K" # Clear line
28-
tput cnorm 2>/dev/null # Show cursor
27+
printf "\r\033[K"
28+
tput cnorm 2>/dev/null
2929
}
3030

3131
# Verify dependencies
3232
if ! command -v mpremote &>/dev/null; then
33-
echo -e "${RED}Warning:${RESET} 'mpremote' is not installed or not in your PATH." >&2
33+
echo -e "${RED}Error:${RESET} 'mpremote' is not installed or not in your PATH." >&2
3434
exit 1
3535
fi
3636

37-
DEVICE=$1
38-
if [ -n "$DEVICE" ]; then
39-
DEVICE="connect $DEVICE"
37+
# Build device connection argument
38+
DEVICE_ARG=""
39+
if [ -n "$1" ]; then
40+
DEVICE_ARG="connect $1"
4041
fi
4142

4243
PROJECT_DIR=$(dirname "$(dirname "$(dirname "$(readlink -f "$0")")")")
4344
LOCAL_DIR="${PROJECT_DIR}/walter_modem"
4445
REMOTE_DIR=":lib/walter_modem"
4546

46-
echo -e "${BOLDWHITE}Verifying directory structure${RESET}"
47-
mpremote $DEVICE fs mkdir ":lib" &>/dev/null || true
48-
mpremote $DEVICE fs mkdir "$REMOTE_DIR" &>/dev/null || true
47+
# Clean and prepare remote directory
48+
echo -e "${BOLDWHITE}Preparing remote directory${RESET}"
49+
mpremote $DEVICE_ARG fs rm -r "$REMOTE_DIR" &>/dev/null || true
50+
mpremote $DEVICE_ARG fs mkdir ":lib" &>/dev/null || true
51+
mpremote $DEVICE_ARG fs mkdir "$REMOTE_DIR" &>/dev/null || true
52+
echo -e " ${RED}[CLEAN]${RESET}${REMOTE_DIR}"
4953

5054
cd "$LOCAL_DIR"
5155

52-
# Create all directories (except .)
53-
echo -e "${BOLDWHITE}Copying library files${RESET}"
54-
find . -type d | while read -r d; do
55-
[ "$d" = "." ] && continue
56-
mpremote $DEVICE fs mkdir "$REMOTE_DIR/${d#./}" &>/dev/null || true
56+
# Create subdirectories
57+
echo -e "${BOLDWHITE}Creating directory structure${RESET}"
58+
find . -type d ! -name '.' | sort | while read -r d; do
59+
mpremote $DEVICE_ARG fs mkdir "$REMOTE_DIR/${d#./}" &>/dev/null || true
5760
echo -e " ${BLUE}[DIR]${RESET} ${REMOTE_DIR}/${d#./}"
5861
done
5962

6063
# Copy all files except *.pyi
61-
find . -type f ! -name '*.pyi' | while read -r f; do
64+
echo -e "${BOLDWHITE}Copying library files${RESET}"
65+
find . -type f ! -name '*.pyi' | sort | while read -r f; do
6266
printf " ${YELLOW}${RESET} ${REMOTE_DIR}/${f#./}"
63-
(
64-
mpremote $DEVICE fs cp "$LOCAL_DIR/$f" "$REMOTE_DIR/${f#./}" &>/dev/null
65-
) &
66-
cp_pid=$!
67-
spinner $cp_pid
67+
(mpremote $DEVICE_ARG fs cp "$f" "$REMOTE_DIR/${f#./}" &>/dev/null) &
68+
spinner $!
6869
echo -e "\r ${GREEN}[FILE]${RESET} ${REMOTE_DIR}/${f#./}"
6970
done
7071

71-
echo -e "${BOLDWHITE}Cleaning up remote files not present locally${RESET}"
72-
73-
# ---
74-
75-
REMOTE_LIST=$(mpremote $DEVICE fs ls -r "$REMOTE_DIR" | awk '{$1=""; print substr($0,2)}' | sed 's|^/||')
76-
LOCAL_LIST=$(find . -type f ! -name '*.pyi' -printf "%P\n"; find . -type d -printf "%P/\n")
77-
78-
# Clean up remote files/dirs not present locally
79-
CLEANED_REMOTE_LIST=()
80-
for entry in $REMOTE_LIST; do
81-
if [[ "$entry" == "$REMOTE_DIR/"* ]]; then
82-
cleaned="${entry#$REMOTE_DIR/}"
83-
else
84-
cleaned="$entry"
85-
fi
86-
[[ -z "$cleaned" || "$cleaned" == "$REMOTE_DIR" || "$cleaned" == "." ]] && continue
87-
[[ "$cleaned" == "$REMOTE_DIR"* ]] && continue
88-
CLEANED_REMOTE_LIST+=("$cleaned")
89-
done
90-
91-
for remote_item in "${CLEANED_REMOTE_LIST[@]}"; do
92-
if ! grep -Fxq "$remote_item" <<< "$LOCAL_LIST"; then
93-
echo -e " ${RED}[REMOVED]${RESET} ${REMOTE_DIR}/$remote_item"
94-
mpremote $DEVICE fs rm "$REMOTE_DIR/$remote_item" &>/dev/null || \
95-
mpremote $DEVICE fs rmdir "$REMOTE_DIR/$remote_item" &>/dev/null || true
96-
fi
97-
done
98-
9972
echo -e "${BOLDWHITE}Sync Complete!${RESET}"

util/modem_passthrough/modem_passthrough.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def build_ui(self):
8181
self.output_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
8282
for tag, opts in self.output_tags.items():
8383
self.output_text.tag_config(tag, **opts)
84+
self.output_text.tag_config('command', foreground='cyan')
8485

8586
self.command_status_label = tk.Label(
8687
self.root,
@@ -162,7 +163,9 @@ def refresh_ui(self):
162163
self.output_text.config(state=tk.NORMAL)
163164
self.output_text.delete('1.0', tk.END)
164165
for line in display:
165-
if 'ERROR' in line:
166+
if line.startswith('>> '):
167+
tag = 'command'
168+
elif 'ERROR' in line:
166169
tag = 'error'
167170
elif 'OK' in line:
168171
tag = 'ok'
@@ -190,6 +193,18 @@ def refresh_ui(self):
190193
cs_fg = 'black'
191194
self.command_status_label.config(text=self.command_result, fg=cs_fg)
192195

196+
def _attempt_reconnect(self, delay=3):
197+
"""Schedule a reconnection attempt without recursion."""
198+
if not self.running:
199+
return
200+
time.sleep(delay)
201+
self.output_lines = []
202+
self.output_queue.put('[i] >> Retrying device connection...')
203+
self.schedule_refresh()
204+
# Use a new thread to avoid stack buildup from recursion
205+
reconnect_thread = threading.Thread(target=self.start_modem_process, daemon=True)
206+
reconnect_thread.start()
207+
193208
def start_modem_process(self):
194209
try:
195210
self.output_queue.put('[i] >> Starting modem process...')
@@ -227,57 +242,54 @@ def start_modem_process(self):
227242
if 'Local directory .' not in line:
228243
self.output_queue.put(line.strip())
229244
self.schedule_refresh()
230-
231-
def attempt_reconnect():
232-
time.sleep(3)
233-
self.output_lines = []
234-
self.output_queue.put(f'[i] >> Retrying device connection...')
235-
self.schedule_refresh()
236-
self.start_modem_process()
237245

238-
proc.stdout.close(); proc.wait()
246+
proc.stdout.close()
247+
proc.wait()
239248
self.output_queue.put('[i] >> Modem process terminated.')
240249
self.passthrough_state = 'NO COMM'
241250
self.schedule_refresh()
242-
attempt_reconnect()
251+
self._attempt_reconnect(delay=3)
243252
except FileNotFoundError as e:
244253
if self.logging: self.log(line='===== PROGRAM CRASHED =====\n', raw=True)
245254
self.output_queue.put(f'[i] >> Error: {e}')
246255
self.passthrough_state = 'ERROR'
247256
self.schedule_refresh()
248-
attempt_reconnect()
257+
self._attempt_reconnect(delay=3)
249258
except Exception as e:
250259
if self.logging: self.log(line='===== PROGRAM CRASHED (Device disconnect?) =====\n', raw=True)
251260
self.output_queue.put(f'[i] >> Error in modem process: {e}')
252261
self.passthrough_state = 'NO COMM'
253262
self.schedule_refresh()
254-
time.sleep(7)
255-
self.start_modem_process()
263+
self._attempt_reconnect(delay=7)
256264

257265
def log(self, line, meta=None, raw=False):
258266
try:
259-
with open(LOG_FILE, 'a+') as f:
267+
with open(LOG_FILE, 'a') as f:
260268
if raw:
261269
f.write(line)
262270
else:
263271
ts = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
264272
f.write(f"[{ts}] {meta:>9}: {line.strip()}\n")
265-
except:
273+
except OSError:
266274
pass
267275

268276
def read_cmd_file(self):
269277
try:
270-
return open(CMD_FILE,'r').read().strip()
271-
except:
278+
with open(CMD_FILE, 'r') as f:
279+
return f.read().strip()
280+
except OSError:
272281
return 'TUI-ERROR'
273282

274283
def write_cmd_file(self, command):
275284
try:
276-
with open(CMD_FILE,'r+') as f:
277-
if f.read().strip() != 'READ': return False
278-
f.seek(0); f.write(command); f.truncate()
285+
with open(CMD_FILE, 'r+') as f:
286+
if f.read().strip() != 'READ':
287+
return False
288+
f.seek(0)
289+
f.write(command)
290+
f.truncate()
279291
return True
280-
except:
292+
except OSError:
281293
return False
282294

283295
def send_interrupt_and_exit(self):
@@ -302,6 +314,8 @@ def process_command(self):
302314
self.command_result = f'Reserved: {cmd}'
303315
elif self.passthrough_state == 'READY' and self.read_cmd_file()=='READ':
304316
if self.write_cmd_file(cmd):
317+
self.output_queue.put('')
318+
self.output_queue.put(f'>> {cmd}')
305319
self.command_result = f'Sent: {cmd}'
306320
self.passthrough_state = f'WAITING ({cmd})'
307321
self.history.append(cmd); self.history_index=None

0 commit comments

Comments
 (0)