Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -19,6 +19,10 @@ import io
|
|
| 19 |
import threading
|
| 20 |
import queue
|
| 21 |
import time
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
|
| 24 |
class MigrationTool:
|
|
@@ -202,17 +206,57 @@ class MigrationTool:
|
|
| 202 |
new_data = False
|
| 203 |
while not log_queue.empty():
|
| 204 |
try:
|
| 205 |
-
|
| 206 |
-
#
|
| 207 |
-
msg =
|
| 208 |
-
if msg:
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
output_lines.append(clean_line)
|
| 213 |
new_data = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
except queue.Empty:
|
| 215 |
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
return "\n".join(output_lines), new_data
|
| 217 |
|
| 218 |
# Thread-safe migration execution storage
|
|
|
|
| 19 |
import threading
|
| 20 |
import queue
|
| 21 |
import time
|
| 22 |
+
import re
|
| 23 |
+
|
| 24 |
+
# Regex to match ANSI escape codes (like [A, [2K, etc.)
|
| 25 |
+
ANSI_ESCAPE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
| 26 |
|
| 27 |
|
| 28 |
class MigrationTool:
|
|
|
|
| 206 |
new_data = False
|
| 207 |
while not log_queue.empty():
|
| 208 |
try:
|
| 209 |
+
raw_msg = log_queue.get_nowait()
|
| 210 |
+
# 1. Strip ANSI escape codes (those [A, [m, etc.)
|
| 211 |
+
msg = ANSI_ESCAPE.sub('', raw_msg)
|
| 212 |
+
if not msg:
|
| 213 |
+
continue
|
| 214 |
+
|
| 215 |
+
# 2. Process the message line by line
|
| 216 |
+
# We handle \r by treating it as a signal to potentially overwrite the last line
|
| 217 |
+
# We handle \n as a signal to start a new line
|
| 218 |
+
for line in msg.replace('\r', '\n').split('\n'):
|
| 219 |
+
clean_line = line.strip()
|
| 220 |
+
if not clean_line:
|
| 221 |
+
continue
|
| 222 |
+
|
| 223 |
+
# 3. Smart Progress Bar Handling
|
| 224 |
+
# Identify if this line is a progress bar update
|
| 225 |
+
# Progress bars usually look like: "Label: 45%|### | ..."
|
| 226 |
+
is_progress = '%' in clean_line and '|' in clean_line and ('[' in clean_line or ']' in clean_line)
|
| 227 |
+
|
| 228 |
+
if is_progress:
|
| 229 |
+
# Extract the label (everything before the progress bar/percentage)
|
| 230 |
+
# This helps us identify WHICH progress bar to update
|
| 231 |
+
label = clean_line.split('|')[0].split('%')[0].strip()
|
| 232 |
+
# If the label ends with a number (like '45'), try to get the text before it
|
| 233 |
+
label = re.sub(r'\d+$', '', label).strip()
|
| 234 |
+
|
| 235 |
+
found = False
|
| 236 |
+
# Look at the last few lines to see if we're updating an existing bar
|
| 237 |
+
# We only look back ~10 lines to keep it fast
|
| 238 |
+
for i in range(len(output_lines) - 1, max(-1, len(output_lines) - 11), -1):
|
| 239 |
+
if label and label in output_lines[i] and ('%' in output_lines[i] or '|' in output_lines[i]):
|
| 240 |
+
output_lines[i] = clean_line
|
| 241 |
+
found = True
|
| 242 |
+
new_data = True
|
| 243 |
+
break
|
| 244 |
+
|
| 245 |
+
if not found:
|
| 246 |
output_lines.append(clean_line)
|
| 247 |
new_data = True
|
| 248 |
+
else:
|
| 249 |
+
# Regular log message
|
| 250 |
+
output_lines.append(clean_line)
|
| 251 |
+
new_data = True
|
| 252 |
+
|
| 253 |
except queue.Empty:
|
| 254 |
break
|
| 255 |
+
|
| 256 |
+
# Keep the output box from growing infinitely (last 1000 lines)
|
| 257 |
+
if len(output_lines) > 1000:
|
| 258 |
+
output_lines[:] = output_lines[-1000:]
|
| 259 |
+
|
| 260 |
return "\n".join(output_lines), new_data
|
| 261 |
|
| 262 |
# Thread-safe migration execution storage
|