* Added "Recheck for connected device feature" * WIP on progress bar

working for larger transfers * More generated debug files that I will
  probably use to help create tests
This commit is contained in:
2025-08-25 11:18:48 -05:00
committed by Jason Ross
parent ffba056153
commit 7df056ef60
20 changed files with 1895 additions and 24 deletions
+179 -13
View File
@@ -144,18 +144,67 @@ class ADBManager:
return None
def parse_progress(self, text_line: str) -> Optional[int]:
"""Parse progress percentage from ADB output."""
"""Parse progress percentage from ADB output with enhanced patterns for large transfers."""
# Original pattern: (XX%)
m = re.search(r"\((\d{1,3})%\)", text_line)
if m:
pct = int(m.group(1))
if 0 <= pct <= 100:
return pct
# Additional patterns for large transfers
# Pattern: XX% complete
m = re.search(r"(\d{1,3})%\s+complete", text_line, re.IGNORECASE)
if m:
pct = int(m.group(1))
if 0 <= pct <= 100:
return pct
# Pattern: transferred XX%
m = re.search(r"transferred\s+(\d{1,3})%", text_line, re.IGNORECASE)
if m:
pct = int(m.group(1))
if 0 <= pct <= 100:
return pct
# Pattern: XX files pulled/pushed (XX%)
m = re.search(
r"\d+\s+files?\s+(?:pulled|pushed).*?\((\d{1,3})%\)",
text_line,
re.IGNORECASE,
)
if m:
pct = int(m.group(1))
if 0 <= pct <= 100:
return pct
return None
def pull_folder(self, remote_path: str, local_path: str) -> bool:
"""Pull files from Android device to local machine."""
# Normalize paths for better compatibility
local_path = os.path.normpath(local_path)
remote_path = remote_path.strip()
# Ensure local directory exists
try:
os.makedirs(local_path, exist_ok=True)
except Exception as e:
self._update_status(f"Failed to create local directory: {e}")
return False
# For Windows root drives, ensure proper formatting
if os.name == "nt" and len(local_path) == 3 and local_path.endswith(":\\"):
# Root drive path like C:\ - this might cause issues with ADB
self._update_status(
"Warning: Transferring to root drive. Consider using a subfolder."
)
cmd = [ADB_BINARY_PATH, "pull", remote_path, local_path]
# Debug output for troubleshooting
self._update_status(f"Command: adb pull '{remote_path}' '{local_path}'")
try:
# Start with initial progress
self._update_progress(0)
@@ -171,19 +220,59 @@ class ADBManager:
line_count = 0
last_progress = 0
start_time = time.time()
last_update_time = start_time
if proc.stdout:
for line in proc.stdout:
line_count += 1
current_time = time.time()
pct = self.parse_progress(line)
if pct is not None:
# Use explicit progress when available
self._update_progress(pct)
last_progress = pct
last_update_time = current_time
else:
# If no explicit progress, simulate some progress based on activity
if line_count % 5 == 0 and last_progress < 90:
estimated_progress = min(last_progress + 5, 90)
self._update_progress(estimated_progress)
last_progress = estimated_progress
# Improved progress estimation for large transfers
elapsed_time = current_time - start_time
time_since_last_update = current_time - last_update_time
# Calculate progress based on multiple factors
should_update = False
new_progress = last_progress
# Time-based progress (update every 2 seconds)
if time_since_last_update >= 2.0 and last_progress < 95:
# Estimate progress based on activity and time
if line_count > 100:
# For large transfers, use a logarithmic approach
activity_factor = min(
line_count / 1000, 50
) # Max 50% from activity
time_factor = min(
elapsed_time / 60, 40
) # Max 40% from time (assumes 1-2 min transfers)
new_progress = min(activity_factor + time_factor, 95)
else:
# For smaller transfers, use the original approach
new_progress = min(last_progress + 10, 95)
should_update = True
# Line-based progress (for very active transfers)
elif line_count % 50 == 0 and last_progress < 90:
# More conservative line-based updates
increment = max(1, min(5, 90 // (line_count // 50 + 1)))
new_progress = min(last_progress + increment, 90)
should_update = True
# Update progress if needed
if should_update and new_progress > last_progress:
self._update_progress(int(new_progress))
last_progress = new_progress
last_update_time = current_time
self._update_status(line.strip())
@@ -193,7 +282,16 @@ class ADBManager:
self._update_status("Transfer completed successfully.")
return True
else:
self._update_status(f"Transfer failed with code {proc.returncode}")
# Capture error output for better debugging
error_msg = f"Transfer failed with code {proc.returncode}"
if hasattr(proc, "stderr") and proc.stderr:
try:
stderr_output = proc.stderr.read()
if stderr_output:
error_msg += f". Error: {stderr_output}"
except:
pass
self._update_status(error_msg)
return False
except Exception as e:
@@ -202,8 +300,27 @@ class ADBManager:
def push_folder(self, local_path: str, remote_path: str) -> bool:
"""Push files from local machine to Android device."""
# Normalize paths for better compatibility
local_path = os.path.normpath(local_path)
remote_path = remote_path.strip()
# Validate local path exists
if not os.path.exists(local_path):
self._update_status(f"Local path does not exist: {local_path}")
return False
# For Windows root drives, ensure proper formatting
if os.name == "nt" and len(local_path) == 3 and local_path.endswith(":\\"):
# Root drive path like C:\ - this might cause issues with ADB
self._update_status(
"Warning: Pushing from root drive. Consider using a subfolder."
)
cmd = [ADB_BINARY_PATH, "push", local_path, remote_path]
# Debug output for troubleshooting
self._update_status(f"Command: adb push '{local_path}' '{remote_path}'")
try:
# Start with initial progress
self._update_progress(0)
@@ -222,19 +339,59 @@ class ADBManager:
line_count = 0
last_progress = 0
start_time = time.time()
last_update_time = start_time
if proc.stdout:
for line in proc.stdout:
line_count += 1
current_time = time.time()
pct = self.parse_progress(line)
if pct is not None:
# Use explicit progress when available
self._update_progress(pct)
last_progress = pct
last_update_time = current_time
else:
# If no explicit progress, simulate some progress based on activity
if line_count % 5 == 0 and last_progress < 90:
estimated_progress = min(last_progress + 5, 90)
self._update_progress(estimated_progress)
last_progress = estimated_progress
# Improved progress estimation for large transfers
elapsed_time = current_time - start_time
time_since_last_update = current_time - last_update_time
# Calculate progress based on multiple factors
should_update = False
new_progress = last_progress
# Time-based progress (update every 2 seconds)
if time_since_last_update >= 2.0 and last_progress < 95:
# Estimate progress based on activity and time
if line_count > 100:
# For large transfers, use a logarithmic approach
activity_factor = min(
line_count / 1000, 50
) # Max 50% from activity
time_factor = min(
elapsed_time / 60, 40
) # Max 40% from time (assumes 1-2 min transfers)
new_progress = min(activity_factor + time_factor, 95)
else:
# For smaller transfers, use the original approach
new_progress = min(last_progress + 10, 95)
should_update = True
# Line-based progress (for very active transfers)
elif line_count % 50 == 0 and last_progress < 90:
# More conservative line-based updates
increment = max(1, min(5, 90 // (line_count // 50 + 1)))
new_progress = min(last_progress + increment, 90)
should_update = True
# Update progress if needed
if should_update and new_progress > last_progress:
self._update_progress(int(new_progress))
last_progress = new_progress
last_update_time = current_time
self._update_status(line.strip())
@@ -244,7 +401,16 @@ class ADBManager:
self._update_status("Transfer completed successfully.")
return True
else:
self._update_status(f"adb push failed with return code {proc.returncode}")
# Capture error output for better debugging
error_msg = f"Push failed with code {proc.returncode}"
if hasattr(proc, "stderr") and proc.stderr:
try:
stderr_output = proc.stderr.read()
if stderr_output:
error_msg += f". Error: {stderr_output}"
except:
pass
self._update_status(error_msg)
return False