Skip to content

Instantly share code, notes, and snippets.

@thomasahle
Created October 31, 2024 10:37
Show Gist options
  • Save thomasahle/0de50c8a537a9335c266f97ffac664cb to your computer and use it in GitHub Desktop.
Save thomasahle/0de50c8a537a9335c266f97ffac664cb to your computer and use it in GitHub Desktop.
import asyncio
import asyncssh
import re
from nicegui import ui
# SSH connection details
SSH_HOST = 'remote_host'
SSH_PORT = 22
SSH_USERNAME = 'username'
SSH_PASSWORD = 'password'
# Global SSH client variable
ssh_client = None
# Regular expression to parse rsync progress
progress_pattern = re.compile(r'^\s*(\d+)%')
async def connect_ssh():
"""Connects to the remote SSH server."""
global ssh_client
ssh_progress.value = 0.1
try:
ssh_client = await asyncssh.connect(
SSH_HOST,
port=SSH_PORT,
username=SSH_USERNAME,
password=SSH_PASSWORD
)
ssh_progress.value = 1.0
except Exception as e:
ssh_progress.value = 0.0
ui.notify(f'SSH connection failed: {e}', color='red')
async def copy_file():
"""Copies the archive from SMB share to temp folder with progress."""
copy_command = 'rsync -a --info=progress2 /mnt/smb_share/archive.zip /tmp/archive.zip'
try:
async with ssh_client.create_process(copy_command) as process:
while True:
line = await process.stderr.readline()
if not line:
break
line = line.strip()
match = re.search(r'(\d+)%', line)
if match:
percent = int(match.group(1)) / 100
copy_progress.value = percent
await asyncio.sleep(0) # Yield control to the event loop
copy_progress.value = 1.0
except Exception as e:
copy_progress.value = 0.0
ui.notify(f'File copy failed: {e}', color='red')
async def unarchive_file():
"""Unarchives the copied file with progress."""
unarchive_command = 'unzip -o "/tmp/archive.zip" -d "/tmp/archive_contents"'
try:
async with ssh_client.create_process(unarchive_command) as process:
total_files = 0
extracted_files = 0
while True:
line = await process.stdout.readline()
if not line:
break
line = line.strip()
if line.startswith(' inflating:'):
extracted_files += 1
if total_files:
percent = extracted_files / total_files
unarchive_progress.value = percent
elif line.startswith('extracting:'):
extracted_files += 1
if total_files:
percent = extracted_files / total_files
unarchive_progress.value = percent
elif line.startswith(' creating:'):
pass # Directory creation, can be ignored or counted
elif 'extracting:' in line:
total_files += 1
await asyncio.sleep(0)
unarchive_progress.value = 1.0
except Exception as e:
unarchive_progress.value = 0.0
ui.notify(f'Unarchive failed: {e}', color='red')
async def start_process():
"""Starts the SSH connection, file copy, and unarchiving process."""
ssh_progress.value = 0.0
copy_progress.value = 0.0
unarchive_progress.value = 0.0
await connect_ssh()
if ssh_client:
await copy_file()
await unarchive_file()
ssh_client.close()
ui.notify('Process completed successfully!', color='green')
with ui.card():
ui.label('SSH Connection Progress')
ssh_progress = ui.linear_progress(value=0.0)
ui.label('Copy Progress')
copy_progress = ui.linear_progress(value=0.0)
ui.label('Unarchive Progress')
unarchive_progress = ui.linear_progress(value=0.0)
ui.button('Start', on_click=lambda: asyncio.create_task(start_process()))
ui.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment