update
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
"""
|
||||
Utility functions for running subprocess operations asynchronously without blocking the UI.
|
||||
This module provides helper functions to prevent UI freezes when executing external processes.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
from typing import Callable, List, Optional, Union
|
||||
from gi.repository import GLib
|
||||
|
||||
|
||||
def run_async_subprocess(
|
||||
command: Union[str, List[str]],
|
||||
on_success: Optional[Callable] = None,
|
||||
on_error: Optional[Callable[[Exception], None]] = None,
|
||||
on_complete: Optional[Callable[[], None]] = None,
|
||||
thread_name: str = "async-subprocess"
|
||||
) -> None:
|
||||
"""
|
||||
Run a subprocess command asynchronously in a background thread.
|
||||
|
||||
Args:
|
||||
command: Command to execute (string or list of strings)
|
||||
on_success: Callback function to call on successful completion
|
||||
on_error: Callback function to call when an error occurs (receives exception)
|
||||
on_complete: Callback function to call when operation completes (success or error)
|
||||
thread_name: Name for the background thread
|
||||
"""
|
||||
def worker_thread(user_data):
|
||||
"""Background thread worker function"""
|
||||
try:
|
||||
if isinstance(command, str):
|
||||
subprocess.run(command, shell=True, check=True)
|
||||
else:
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
# Schedule success callback on main thread
|
||||
if on_success:
|
||||
GLib.idle_add(lambda: (on_success(), False))
|
||||
|
||||
except Exception as e:
|
||||
# Schedule error callback on main thread
|
||||
if on_error:
|
||||
GLib.idle_add(lambda: (on_error(e), False))
|
||||
finally:
|
||||
# Schedule completion callback on main thread
|
||||
if on_complete:
|
||||
GLib.idle_add(lambda: (on_complete(), False))
|
||||
|
||||
GLib.Thread.new(thread_name, worker_thread, None)
|
||||
|
||||
|
||||
def check_process_async(
|
||||
process_name: str,
|
||||
on_running: Optional[Callable[[], None]] = None,
|
||||
on_not_running: Optional[Callable[[], None]] = None,
|
||||
on_error: Optional[Callable[[Exception], None]] = None,
|
||||
thread_name: str = "check-process"
|
||||
) -> None:
|
||||
"""
|
||||
Check if a process is running asynchronously.
|
||||
|
||||
Args:
|
||||
process_name: Name of the process to check (used with pgrep)
|
||||
on_running: Callback function to call if process is running
|
||||
on_not_running: Callback function to call if process is not running
|
||||
on_error: Callback function to call when an error occurs
|
||||
thread_name: Name for the background thread
|
||||
"""
|
||||
def worker_thread(user_data):
|
||||
"""Background thread worker function"""
|
||||
try:
|
||||
subprocess.check_output(["pgrep", process_name])
|
||||
# Process is running
|
||||
if on_running:
|
||||
GLib.idle_add(lambda: (on_running(), False))
|
||||
except subprocess.CalledProcessError:
|
||||
# Process is not running
|
||||
if on_not_running:
|
||||
GLib.idle_add(lambda: (on_not_running(), False))
|
||||
except Exception as e:
|
||||
# Other error occurred
|
||||
if on_error:
|
||||
GLib.idle_add(lambda: (on_error(e), False))
|
||||
|
||||
GLib.Thread.new(thread_name, worker_thread, None)
|
||||
|
||||
|
||||
def run_command_with_output_async(
|
||||
command: Union[str, List[str]],
|
||||
on_success: Optional[Callable[[bytes], None]] = None,
|
||||
on_error: Optional[Callable[[Exception], None]] = None,
|
||||
thread_name: str = "command-output"
|
||||
) -> None:
|
||||
"""
|
||||
Run a command and capture its output asynchronously.
|
||||
|
||||
Args:
|
||||
command: Command to execute (string or list of strings)
|
||||
on_success: Callback function to call with command output on success
|
||||
on_error: Callback function to call when an error occurs
|
||||
thread_name: Name for the background thread
|
||||
"""
|
||||
def worker_thread(user_data):
|
||||
"""Background thread worker function"""
|
||||
try:
|
||||
if isinstance(command, str):
|
||||
result = subprocess.run(command, shell=True, capture_output=True, check=True)
|
||||
else:
|
||||
result = subprocess.run(command, capture_output=True, check=True)
|
||||
|
||||
# Schedule success callback with output on main thread
|
||||
if on_success:
|
||||
GLib.idle_add(lambda: (on_success(result.stdout), False))
|
||||
|
||||
except Exception as e:
|
||||
# Schedule error callback on main thread
|
||||
if on_error:
|
||||
GLib.idle_add(lambda: (on_error(e), False))
|
||||
|
||||
GLib.Thread.new(thread_name, worker_thread, None)
|
||||
Reference in New Issue
Block a user